Linux C 多執行緒程式設計條件變數

2021-08-04 15:08:42 字數 3858 閱讀 4170

二、條件變數

這裡主要說說

pthread_cond_wait()的用法,在下面有說明。

條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:一

個執行緒等待"條件變數的條件成立"而掛起;另乙個執行緒使"條件成立"(給出條件成立訊號)。為了防止競爭,條件變數的使用總是和乙個互斥鎖結合在一起。   

1.   建立和登出   

條件變數和互斥鎖一樣,都有靜態動態兩種建立方式,靜態方式使用pthread_cond_initializer常量,如下:     

pthread_cond_t   cond=pthread_cond_initializer     

動態方式呼叫pthread_cond_init()函式,api定義如下:     

int   pthread_cond_init(pthread_cond_t   *cond,   pthread_condattr_t   *cond_attr)     

儘管posix標準中為條件變數定義了屬性,但在linuxthreads中沒有實現,因此cond_attr值通常為null,且被忽略。   

登出乙個條件變數需要呼叫pthread_cond_destroy(),只有在沒有執行緒在該條件變數上等待的時候才能登出這個條件變數,否則返回ebusy。因為linux實現的條件變數沒有分配什麼資源,所以登出動作只包括檢查是否有等待執行緒。api定義如下:     

int   pthread_cond_destroy(pthread_cond_t   *cond)

2.   等待和激發   

int   pthread_cond_wait(pthread_cond_t   *cond,   pthread_mutex_t   *mutex)

執行pthread_cond_wait()時

自動解鎖互斥量(如同執行了 pthread_unlock_mutex),並等待條件變數觸發。這時執行緒掛起,不占用 cpu 時間,直到條件變數被觸發。

因此,全過程可以描述為:

(1)pthread_mutex_lock()上鎖,

(2)pthread_cond_wait()等待,等待過程分解為為:解鎖--條件滿足--加鎖

(3)pthread_mutex_unlock()解鎖。

激發條件有兩種形式,pthread_cond_signal()啟用乙個等待該條件的執行緒,存在多個等待執行緒時按入隊順序啟用其中乙個;而pthread_cond_broadcast()則啟用所有等待執行緒。 兩者 如果沒有等待的執行緒,則什麼也不做。

下面一位童鞋問的問題解釋了上面的說明:

當pthread_cond_t呼叫pthread_cond_wait進入等待狀態時,pthread_mutex_t互斥訊號無效了.

示例**如下:

//多執行緒同步--條件鎖(相當與windows的事件)測試

//要先讓pthread_cond_wait進入等待訊號狀態,才能呼叫pthread_cond_signal傳送訊號,才有效.

//不能讓pthread_cond_signal在pthread_cond_wait前面執行

#include

#include//多執行緒所用標頭檔案

#include //訊號量使用標頭檔案

pthread_cond_t g_cond /*=pthread_mutex_initializer*/; //申明條鎖,並用巨集進行初始化

pthread_mutex_t g_mutex ;

//執行緒執行函式

void threadfun1(void)

pthread_cond_signal(&g_cond);

pthread_mutex_unlock(&g_mutex);

}int main(void)

sleep(5); //等待子執行緒先開始

pthread_mutex_lock(&g_mutex); //2

pthread_cond_signal(&g_cond); //給個開始訊號,注意這裡要先等子執行緒進入等待狀態在發訊號,否則無效

pthread_mutex_unlock(&g_mutex);

pthread_join(id1,null);

pthread_cond_destroy(&g_cond); //釋放

pthread_mutex_destroy(&g_mutex); //釋放

return 0;

}大家請看紅顏色的1和2.

明明是1先鎖了互斥變數,但**執行到2還是一樣可以鎖定.

為什麼會這樣呢????/

pthread_cond_wait()什麼情況才會接鎖,繼續跑下去啊...現在來看一段典型的應用:看注釋即可。

問題解釋:當程式進入pthread_cond_wait等待後,將會把g_mutex進行解鎖,當離開pthread_cond_wait之前,g_mutex會重新加鎖。所以在main中的g_mutex會被加鎖。 呵呵。。。

現在來看一段典型的應用:看注釋即可。

#include

#include

static pthread_mutex_t mtx = pthread_mutex_initializer;    

static pthread_cond_t cond = pthread_cond_initializer;    

struct node *head = null;    

/*[thread_func]*/    

static void cleanup_handler(void *arg)    

static void *thread_func(void *arg)    

shared = ;

void    *produce(void *), *consume(void *);

/* include main */

intmain(int 

argc

, char **argv)

nitems = min(atoi(argv[1]), maxnitems);

nthreads = min(atoi(argv[2]), maxnthreads);

/* 4create all producers and one consumer */

for (i = 0; i < nthreads; i++)

pthread_create(&tid_consume, null, consume, null);

/* 4wait for all producers and the consumer */

for (i = 0; i < nthreads; i++)

pthread_join(tid_consume, null);

exit(0);

}/* end main */

void *

produce(void *arg)

shared.buff[shared.nput] = shared.nval;

shared.nput++;

shared.nval++;

pthread_mutex_unlock(&shared.mutex);

*((int *) arg) += 1;}}

/* include consume */

void

consume_wait(int i)

pthread_mutex_unlock(&shared.mutex);}}

void *

consume(void *arg)

return(null);

}

Linux C 多執行緒程式設計互斥鎖與條件變數

linux c 多執行緒程式設計互斥鎖與條件變數 include mylib.h define buffer size 5 產品庫存大小 define product cnt 30 產品生產總數 struct product cons buffer void init struct product ...

多執行緒程式設計 條件變數

條件變數 條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起 另乙個執行緒使 條件成立 給出條件成立訊號 為了防止競爭,條件變數的使用總是和乙個互斥鎖結合在一起。1.建立和登出 條件變數和互斥鎖一樣,都有靜態和動態兩種建立方式,靜態...

多執行緒程式設計 條件變數

include include include include 靜態方式初始化乙個互斥鎖和乙個條件變數 static pthread mutex t mutex pthread mutex initializer static pthread cond t cond pthread cond ini...