linux 執行緒 條件變數

2021-09-29 07:39:32 字數 4042 閱讀 9298

條件變數本身不是鎖!但它也可以造成執行緒阻塞。通常與互斥鎖配合使用。給多執行緒提供乙個會合的場所(共享的資料)。主要應用函式:

pthread_cond_init函式        pthread_cond_destroy函式

pthread_cond_wait函式       pthread_cond_timedwait函式

pthread_cond_signal函式      pthread_cond_broadcast函式

以上6 個函式的返回值都是:成功返回0, 失敗直接返回錯誤號。

pthread_cond_t型別  用於定義條件變數    pthread_cond_t cond;

引入條件變數的目的:在使用互斥鎖的基礎上引入條件變數可以使程式的效率更高,因為條件變數的引入明顯減少了執行緒取競爭互斥鎖的次數。執行pthread_cond_wait或pthread_cond_timedwait函式的執行緒明顯知道了條件不滿足,要因此在其釋放鎖之後就沒有必要再跟其它執行緒去競爭鎖了,只需要阻塞等待signal或broadcast函式將其喚醒。這樣提高了效率。

(1)pthread_cond_init函式

int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

作用:初始化乙個條件變數

參2:attr表條件變數屬性,通常為預設值,傳null即可。也可以使用靜態初始化的方法,初始化條件變數:pthread_cond_t cond = pthread_cond_initializer;

(2)pthread_cond_destroy函式

int pthread_cond_destroy(pthread_cond_t *cond);

作用:銷毀乙個條件變數

(3)pthread_cond_wait函式

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

作用:阻塞等待條件變數cond(形參1)滿足條件,且釋放已經掌握的互斥鎖(解鎖互斥量)相當於pthread_mutex_unlock(&mutex)(注意這是乙個原子操作,即阻塞等待的同時馬上解鎖,類似sigsuspend函式);當被喚醒(signal或broadcast函式),pthread_cond_wait函式返回,解除阻塞並重新申請獲取互斥鎖:pthread_mutex_lock(&mutex);

(4)pthread_cond_timedwait函式

int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

作用:與pthread_cond_wait函式作用相同,但其限時等待乙個條件變數,即如果在規定的時間點(第三個形參)還未被喚醒時,該執行緒自動喚醒並解除阻塞重新申請獲取互斥鎖:pthread_mutex_lock(&mutex);

引數3:struct timespec結構體。

struct timespec ;  pthread_cond_timedwait (&cond, &mutex, &t); 只能定時到 2023年1月1日 00:00:01秒(早已經過去)。 2023年1月1日 00:00:00秒作為計時元年。正確用法:

time_t cur = time(null);   //獲取當前時間(絕對時間)

struct timespec t;             //定義timespec 結構體變數t

t.tv_sec = cur+1;   //定時1秒

pthread_cond_timedwait (&cond, &mutex, &t); 傳參   參考apue.11.6執行緒同步條件變數小節

在講解setitimer函式時我們還提到另外一種時間型別:

struct timeval ;                  

struct production *head = null;  //定義全域性指標head

struct production *rer = null;   //定義全域性指標rer

pthread_mutex_t mutex = pthread_mutex_initializer;  //靜態初始化

pthread_cond_t cond = pthread_cond_initializer;  //靜態初始化

void *productor( void *arg )    //生產者  

return null;} 

void *consumer( void *arg )  //消費者

return null;} 

int main( void )

ret = pthread_create( &cid, null, consumer, null);

if( ret != 0)

ret = pthread_join(pid,null);

if( ret != 0)

ret = pthread_join(cid,null);

if( ret != 0)

pthread_cond_destroy(&cond);         //銷毀條件變數

pthread_mutex_destroy(&mutex);       //銷毀互斥鎖

return 0;

}[root@localhost 02_pthread_sync_test]# ./pthrd_cond

--------the production is 257.

++++++++the consumer is 257.

--------the production is 324.

--------the production is 327.

++++++++the consumer is 327.

--------the production is 180.

--------the production is 313.

++++++++the consumer is 313.

--------the production is 285.

++++++++the consumer is 285.

++++++++the consumer is 180.

++++++++the consumer is 324.

--------the production is 21.

--------the production is 351.

++++++++the consumer is 351.

分析:將生產者與消費者共享的資源(產品)用鍊錶這種資料結構表示,head始終指向煉表表頭,rer用於向鍊錶中增加或刪除元素時的中間過渡。注意:這裡的head與rer都是全域性指標,都會被所有的消費者和生產者執行緒所共享,因此訪問這兩個資源時,都必須採用互斥鎖,即先加鎖,再訪問,最後解鎖。否則容易出現段錯誤。

這個程式只是建立了乙個生產者執行緒和乙個消費者執行緒,但是考慮的時候應該考慮有多個生產者執行緒和多個消費者執行緒。每乙個執行緒都是採用互斥鎖訪問共享資源head和rer。通過採用條件變數把執行緒阻塞原因分為三部分:1.生產者因為加鎖時(鎖未解鎖)而阻塞;2.消費者因為加鎖時(鎖未解鎖)而阻塞;3.消費者因為執行了wait而阻塞(這是因為條件不滿足)。這三部分執行緒,每當有鎖解鎖時,只有前兩部分執行緒會去競爭,而第三部分執行緒只有等待被喚醒後才會去競爭。因此採用條件變數可以減少互斥鎖的競爭次數。

上述程式中之所以必須採用while,是因為當因為wait阻塞而喚醒的執行緒,即使搶到了鎖,公共資源也可能被其餘消費者消耗了(因為生產者在signal之前會解鎖,而解鎖會引發消費者再次競爭鎖),因此必須再次判斷共享資源是否為空。

這道題目如果對共享資源的最大數量有限制,那麼生產者執行緒也要引入條件變數。

相較於mutex而言,條件變數可以減少競爭。如直接使用mutex,除了生產者、消費者之間要競爭互斥量以外,消費者之間也需要競爭互斥量,但如果匯聚(鍊錶)中沒有資料,消費者之間競爭互斥鎖是無意義的。有了條件變數機制以後,只有生產者完成生產,才會引起消費者之間的競爭。提高了程式效率。

linux 執行緒 條件變數

與互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞乙個執行緒,直到某特殊情況發生為止。條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起 另乙個執行緒使 條件成立 給出條件...

Linux執行緒同步 條件變數

執行緒間的同步還有乙個情況 程序a 需要等待乙個條件成立,才執行,當條件不成立時就阻塞等待 程序b 需要設定條件,當條件成立時,喚醒程序a.這裡我們就可以用到條件變數。條件變數變數也是出自posix執行緒標準,另一種執行緒同步機制,主要用來等待某個條件的發生,然後進行相應的操作,這樣可以消除多執行緒...

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

條件變數通訊機制 基本原理 初始化條件變數 int pthread cond init pthread cond t restrict cond,const pthread condattr t restrict attr pthread cond t cond pthread cond initi...