Linux執行緒同步之條件變數

2021-06-01 20:00:46 字數 3015 閱讀 1413

與互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞乙個執行緒,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用。

條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:乙個執行緒等待"條件變數的條件成立"而掛起;另乙個執行緒使"條件成立"(給出條件成立訊號)。

條件的檢測是在互斥鎖的保護下進行的。如果乙個條件為假,乙個執行緒自動阻塞,並釋放等待狀態改變的互斥鎖。如果另乙個執行緒改變了條件,它發訊號給關聯的條件變數,喚醒乙個或多個等待它的執行緒,重新獲得互斥鎖,重新評價條件。如果兩程序共享可讀寫的記憶體,條件變數可以被用來實現這兩程序間的執行緒同步。

使用條件變數之前要先進行初始化。可以在單個語句中生成和初始化乙個條件變數如:pthread_cond_t my_condition=pthread_cond_initializer;(用於程序間執行緒的通訊)。可以利用函式pthread_cond_init動態初始化。

條件變數分為兩部分: 條件和變數. 條件本身是由互斥量保護的. 執行緒在改變條件狀態前先要鎖住互斥量. 它利用執行緒間共享的全域性變數進行同步的一種機制。

1 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);    

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

3 int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);

4 int pthread_cond_destroy(pthread_cond_t *cond); 

5 int pthread_cond_signal(pthread_cond_t *cond);

6 int pthread_cond_broadcast(pthread_cond_t *cond);  //解除所有執行緒的阻塞

簡要說明:     

(1)初始化.init()或者pthread_cond_t cond=pthread_cond_initialier;屬性置為null

(2)等待條件成立.pthread_wait,pthread_timewait.wait()釋放鎖,並阻塞等待條件變數為真

timewait()設定等待時間,仍未signal,返回etimeout(加鎖保證只有乙個執行緒wait)

(3)啟用條件變數:pthread_cond_signal,pthread_cond_broadcast(啟用所有等待執行緒)

(4)清除條件變數:destroy;無線程等待,否則返回ebusy

詳細說明

1. 初始化:

條件變數採用的資料型別是pthread_cond_t, 在使用之前必須要進行初始化, 這包括兩種方式:

靜態: 可以把常量pthread_cond_initializer給靜態分配的條件變數.

動態: pthread_cond_init函式, 是釋放動態條件變數的記憶體空間之前, 要用pthread_cond_destroy對其進行清理.

#include

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

int pthread_cond_destroy(pthread_cond_t *cond);

成功則返回0, 出錯則返回錯誤編號.

當pthread_cond_init的attr引數為null時, 會建立乙個預設屬性的條件變數; 非預設情況以後討論.

2. 等待條件:

#include

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

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

成功則返回0, 出錯則返回錯誤編號.

這兩個函式分別是阻塞等待和超時等待.

等待條件函式等待條件變為真, 傳遞給pthread_cond_wait的互斥量對條件進行保護, 呼叫者把鎖住的互斥量傳遞給函式. 函式把呼叫執行緒放到等待條件的執行緒列表上, 然後對互斥量解鎖, 這兩個操作是原子的. 這樣便關閉了條件檢查和執行緒進入休眠狀態等待條件改變這兩個操作之間的時間通道, 這樣執行緒就不會錯過條件的任何變化.

當pthread_cond_wait返回時, 互斥量再次被鎖住.

3. 通知條件:

#include

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

成功則返回0, 出錯則返回錯誤編號.

這兩個函式用於通知執行緒條件已經滿足. 呼叫這兩個函式, 也稱向執行緒或條件傳送訊號. 必須注意, 一定要在改變條件狀態以後再給執行緒傳送訊號.

int main()

while (1);

sleep(20);

pthread_exit(0);

return 0;

條件變數與互斥鎖、訊號量的區別

1.互斥鎖必須總是由給它上鎖的執行緒解鎖,訊號量的掛出即不必由執行過它的等待操作的同一程序執行。乙個執行緒可以等待某個給定訊號燈,而另乙個執行緒可以掛出該訊號燈。

2.互斥鎖要麼鎖住,要麼被解開(二值狀態,型別二值訊號量)。

3.由於訊號量有乙個與之關聯的狀態(它的計數值),訊號量掛出操作總是被記住。然而當向乙個條件變數傳送訊號時,如果沒有執行緒等待在該條件變數上,那麼該訊號將丟失。

4.互斥鎖是為了上鎖而設計的,條件變數是為了等待而設計的,訊號燈即可用於上鎖,也可用於等待,因而可能導致更多的開銷和更高的複雜性。

Linux執行緒同步之 條件變數

條件變數是執行緒可用的另一種同步機制。條件變數給多執行緒提供了乙個會合的場所。它主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起 另乙個執行緒使 條件成立 給出條件成立訊號 條件變數與互斥量一起使用時,允許執行緒以無競爭的方式等待特定的條件發生。條件變數本身是互斥量保護的。執行緒在改變條...

Linux執行緒同步之條件變數

條件變數變數也是出自posix 執行緒標準,另一種執行緒同步機制,主要用來等待某個條件的發生。可以用來同步同一程序中的各個執行緒。當然如果乙個條件變數存放在多個程序共享的某個記憶體區中,那麼還可以通過條件變數來進行程序間的同步。每個條件變數總是和乙個互斥量相關聯,條件本身是由互斥量保護的,執行緒在改...

linux執行緒同步之條件變數

條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補了互斥鎖的不足,它常和互斥鎖一起使用。使用時,條件變數被用來阻塞乙個執行緒,當條件不滿足時,執行緒往往解開相應的互斥鎖並等待條件發生變化。一旦其它的某個執行緒改變了條件變數,它將通知相應的條件變數喚醒乙個或多個正被此條件變數阻塞的執行緒。...