條件變數是執行緒的另一種同步機制。
條件變數與互斥量一起使用時,允許執行緒以無競爭的方式等待特定的條件發生。
條件本身是由互斥量保護的。執行緒在改變條件狀態之前必須首先鎖住互斥量。其他執行緒在獲得互斥量之前不會察覺到這種改變,因為互斥量必須在鎖定以後才能計算條件。
使用條件變數前,必須先對它進行初始化。條件變數的資料型別為pthread_cond_t。它有兩種初始化方式:
1、直接把常量pthread_cond_initializer賦值給靜態分配的條件變數。
2、如果條件變數是動態分配的,需要使用pthread_cond_init函式對它進行初始化。
在釋放條件變數底層的記憶體空間前,可以使用pthread_cond_destroy函式對條件變數進行銷毀。
注意:不能用多個執行緒初始化同乙個條件變數,當乙個執行緒要使用條件變數的時候確保它是未被使用的。
#include
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
//兩個函式的返回值:若成功,返回0;否則,返回錯誤編碼
除非需要建立乙個具有非預設屬性的條件變數,否則pthread_cond_init函式的attr引數可以設定為 null。
我們使用pthread_cond_wait等待條件變數變為真。如果在給定的時間內條件不能滿足,那麼會生成乙個返回錯誤碼的變數。
#include
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const
struct timespec *restrict tsptr);
//兩個函式的返回值:若成功,返回0;否則,返回錯誤編碼
傳遞給pthread_cond_wait的互斥量對條件進行保護。呼叫者把鎖住的互斥量傳給函式,函式然後自動把呼叫執行緒放到等待條件的執行緒列表上,對互斥量解鎖。
這就關閉了條件檢查和執行緒進入休眠狀態等待條件改變這兩個操作之間的時間通道,這樣執行緒就不會錯過條件的任何變化。pthread_cond_wait返回時,互斥量再次被鎖住。
pthread_cond_timedwait函式的功能與pthread_cond_wait函式相似,只是多了乙個超時( tsptr)。超時值指定了我們願意等待多長時間,它是通過timespec結構指定的。
使用方式:
使用pthread_cond_wait方式如下:
pthread _mutex_lock(&mutex)
while或if(執行緒執行的條件是否成立)
pthread_cond_wait(&cond, &mutex);
/* 執行緒執行語句 */
pthread_mutex_unlock(&mutex);
這裡在呼叫pthread_cond_wait前需要互斥量進行加鎖的原因是:確保在公有資源條件狀態改變時,等待條件的執行緒已經被放到等待條件的執行緒列表上。
使用while和if判斷執行緒執行條件是否成立的區別:
一般來說,在多執行緒資源競爭的時候,在乙個使用資源的執行緒裡面(消費者)判斷資源是否可用,不可用便呼叫pthread_cond_wait,在另乙個執行緒裡面(生產者)如果判斷資源可用的話,則呼叫pthread_cond_signal傳送乙個資源可用訊號,這時候pthread_cond_wait就會返回,並且會再自動對互斥量進行加鎖,然後執行緒接著執行下去。
下面是流程:
等待執行緒:
pthread_cond_wait前要先加鎖
pthread_cond_wait內部會解鎖,然後等待條件變數被其它執行緒啟用
pthread_cond_wait被啟用後會再自動加鎖
啟用執行緒:
加鎖(和等待執行緒用同乙個鎖)
pthread_cond_signal傳送訊號(階躍訊號前最好判斷有無等待執行緒)
解鎖
啟用執行緒的三個操作執行時,等待執行緒都處於pthread_cond_wait中,等待pthread_cond_signal傳送訊號啟用。
#include
struct msge ;
struct msge *workq;
pthread_cond_t qready = pthread_cond_initializer;
pthread_mutex_t qlock = pthread_mutex_initializer;
//等待條件(消費者)執行緒1
void process_msg(void)
mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
/* now process the message mp */
}}//產生條件(生產者)執行緒2
void enqueue_msg(struct msge *mp)
這裡用兩個執行緒分別模擬生產者與消費者,消費者執行緒等待生產者執行緒產生特定的條件,然後再往下執行,這裡因為是兩個執行緒,所以生產者如果先於消費者獲得互斥量並呼叫了pthread_cond_signal,消費者因為還沒有進入等待條件狀態,所以生產者傳送的訊號,消費者會忽略掉。 執行緒同步 條件變數
當我們需要控制對記憶體資源的訪問的時候,可以用一種簡單的加鎖的方法來控制,即互斥鎖。但互斥鎖有乙個明顯的缺點,就是它只有兩個狀態 鎖定和非鎖定。而條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補來互斥鎖的不足。條件變數通常和互斥鎖一起使用。使用過程 1.呼叫pthread mutex ...
執行緒同步 條件變數
1.問題引入 互斥鎖問題,假設現在有兩個資源a和b,乙個執行緒先拿a再拿b,另乙個則相反,這樣導致的問題就是死鎖,即兩個執行緒無休止的互相等待 include include include include pthread mutex t g mtxa pthread mutex initializ...
執行緒同步 條件變數
多執行緒中條件變數的使用 執行緒同步之條件變數 include include include include include include include include using namespace std 乙個簡單的緩衝區類 struct buffer bool full return f...