linux線程操作


初始化條件變量

int pthread_cond_init(pthread_cond_t *cv,pthread_cond_attr *cattr);
函數返回值:返回0表示成功,返回其他表示失敗。
參數:        pthread_cond_attr是用來設置pthread_cond_t的屬性,當傳入的值是NULL的時候表示使用默認的屬性。

函數返回時,創建的條件變量保存在cv所指向的內存中,可以用宏PTHREAD_COND_INITIALIZER來初始化條件變量。值得注意的是不能使用多個線程初始化同一個條件變量,當一個線程要使用條件變量的時候確保它是未被使用的。

 

條件變量的銷毀

int pthread_cond_destroy(pthread_cond_t *cv);
返回值:返回0表示成功,返回其他值表示失敗。

 

條件變量的使用:

int pthread_cond_wait(pthread_cond_t *cv,pthread_mutex_t *mutex)
int pthread_cond_signal(pthread_cond_t *cv);

 

使用方式如下:

pthread_mutex_lock(&mutex)
while or if(線程執行的條件是否成立)
    pthread_cond_wait(&cond,&mutex);
線程執行
pthread_mutex_unlock(&mutex);

 

 

為什么要加鎖

  1. 線程在執行的部分訪問的是進程的資源,有可能多個線程需要訪問它,為了避免由於線程並發執行所引起的資源競爭,所以要讓每個線程互斥的訪問公共資源。
  2. 如果while或if判斷不滿足線程的執行條件時,線程回調用pthread_cond_wait阻塞自己。pthread_cond_wait被調用線程阻塞的時候,pthread_cond_wait會自動釋放互斥鎖。線程從調用pthread_cond_wait到操作系統把他放在線程等待隊列之后的時候釋放互斥鎖。

 

使用while和if判斷線程執行條件釋放成立的區別。

在多線程資源競爭的時候,在一個使用資源的線程里面(消費者)判斷資源是否可用,不可用便調用pthread_cond_wait,在另一個線程里面(生產者)如果判斷資源可用的話,則會調用pthead_cond_signal發送一個資源可用的信號。

但是在wait成功之后,資源就不一定可以被使用,因為同時有兩個或兩個以上的線程正在等待次資源,wait返回后,資源可能已經被使用了,在這種情況下

while(resource == FALSE)
    pthread_cond_wait(&cond,&mutex);

如果之后只有一個消費者,就可使用if。

分解pthread_cond_wait動作為以下步驟:

  1. 線程放在等待隊列上,解鎖
  2. 等待pthread_cond_signal或者pthread_cond_broadcast信號之后去競爭鎖
  3. 若競爭到互斥鎖則加鎖

 

有可能多個線程在等待這個資源可用的信號,信號發出去之后只有一個資源可用,但是有A,B兩個線程在等待,B速度比較快,獲得互斥鎖,然后加鎖,消耗資源,然后解鎖,之后A獲得互斥鎖,但它回去發現資源已經被使用了,它便有兩個選擇,一個失去訪問不存在的資源,另一個就是繼續等待,那么等待下去的條件就是使用while,要不然使用if的話pthread_cond_wait返回后,就會順序執行下去。

 

等待線程:

pthread_cond_wait      前要加鎖

pthread_cond_wait      內部會解鎖,然后等待條件變量被其他線程激活

pthread_cond_wait      被激活后會再自動加鎖

 

激活線程

加鎖(和等待線程用同一個鎖)

pthread_cond_signal   發送信號(階躍信號前最后判斷有無等待線程)

解鎖

激活線程的上面三個操作再運行時間上都是再等待線程的pthread_cond_wait函數內部。

/***
pthread_if.c
***/
#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int count = 0;

void *decrement(void *arg)
{
    printf("in derment\n");
    pthread_mutex_lock(&mutex);
    if(count == 0)
        pthread_cond_wait(&cond,&mutex);
    count--;
    printf("----decrement:%d\n",count);
    printf("out decrement\n");
    pthread_mutex_unlock(&mutex);
    return NULL;
}

void *increment(void *arg)
{
    printf("in increment\n");
    pthread_mutex_lock(&mutex);
    count++;
    printf("-----increment:%d\n",count);
    if(count != 0)
    {
        pthread_cond_signal(&cond);
    }
    printf("out increment\n");
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main()
{
    pthread_t tid_in,tid_de;
    pthread_create(&tid_de,NULL,(void*)decrement,NULL);
    sleep(1);
    pthread_create(&tid_in,NULL,(void*)increment,NULL);
    sleep(1);

    pthread_join(tid_de,NULL);
    pthread_join(tid_in,NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

 

 

/***
pthread_while.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>

typedef struct node_s
{
    int data;
    struct node_s *next;
}node_t;

node_t *head = NULL;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void cleanup_handler(void *arg)
{
    printf("cleanup_handler is running.\n");
    free(arg);
    pthread_mutex_unlock(&mutex);
}

void *thread_func(void *arg)
{
    node_t *p = NULL;
    pthread_cleanup_push(cleanup_handler,p);
    while(1)
    {
        pthread_mutex_lock(&mutex);
        while(NULL == head)
            pthread_cond_wait(&cond,&mutex);
        p = head;
        head = head->next;
        printf("process %d node\n",p->data);
        free(p);
        pthread_mutex_unlock(&mutex);
    }
    pthread_cleanup_pop(0);
    return NULL;
}

int main()
{
    pthread_t tid;
    node_t *temp = NULL;
    int i;
    pthread_create(&tid,NULL,(void*)thread_func,NULL);

    for(i = 0; i < 10; i++)
    {
        temp = (node_t*)malloc(sizeof(node_t));
        temp->data = i;
        pthread_mutex_lock(&mutex);
        temp->next = head;
        head = temp;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    pthread_cancel(tid);
    pthread_join(tid,NULL);
    return 0;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM