互斥鎖和條件變數的區別與應用

2021-09-11 07:33:18 字數 1942 閱讀 9978

兩個執行緒操作同一臨界區時,通過互斥鎖保護,若a執行緒已經加鎖,b執行緒再加鎖時候會被阻塞,直到a釋放鎖,b再獲得鎖執行,執行緒b必須不停的主動獲得鎖、檢查條件、釋放鎖、再獲得鎖、再檢查、再釋放,一直到滿足執行條件的時候才可以(而此過程中其他執行緒一直在等待該執行緒的結束),這種方式是比較消耗系統資源的。

條件變數同樣是阻塞,還需要通知才能喚醒,執行緒被喚醒後,它將重新檢查判斷條件是否滿足,如果還不滿足,該執行緒就休眠了,仍阻塞在這裡,等待條件滿足後被喚醒,節省了執行緒不斷執行浪費的資源。這個過程一般用while語句實現。

當執行緒b發現被鎖定的變數不滿足條件時會自動的釋放鎖並把自身置於等待狀態,讓出cpu的控制權給其它執行緒。

其它執行緒此時就有機會進行操作,當修改完成後再通知那些由於條件不滿足而陷入等待狀態的執行緒。這是一種通知模型的同步方式,大大的節省了cpu的計算資源,減少了執行緒之間的競爭,而且提高了執行緒之間的系統工作的效率。這種同步方式就是條件變數。

以上說明可能有點抽象,考慮這樣的簡單場景:通過偽**說明。

a執行緒從佇列中取元素,b執行緒往佇列中存放元素。不考慮免鎖的實現。需要乙個mutex用來保護佇列的一致性,避免兩個執行緒同時操作佇列破壞資料結構。

當隊列為空的時候,a需要不斷的探測佇列狀態:

while(1)

else

}這就有乙個問題,可能在剛進入休眠時,b放入元素了,但仍然需要休眠完整個10s的時間。造成不必要的延遲。當然如果不sleep也可以,但會造成不必要的cpu開銷。

使用基於條件變數的事件通知喚醒機制,就可以避免這些問題。

一旦b放入元素完成後就執行pthread_cond_signal(),當前阻塞的執行緒就會立即被喚醒開始幹活兒。

while(1)

注意:條件變數都用互斥鎖進行保護,條件變數狀態的改變都應該先鎖住互斥鎖,

pthread_cond_wait()需要傳入乙個已經加鎖的互斥鎖,該函式把呼叫執行緒加入等待條件的呼叫列表中,然後釋放mutex。

在條件滿足從而離開pthread_cond_wait()時,重新對mutex加鎖,這兩個操作都是原子操作。

pthread_cond_signal通過條件變數cond傳送訊息,若多個訊息在等待,它只喚醒乙個。pthread_cond_broadcast可以喚醒所有。

呼叫pthread_cond_signal後要立刻釋放互斥鎖,因為pthread_cond_wait的最後一步是要將指定的互斥量重新鎖住,如果pthread_cond_signal之後沒有釋放互斥鎖,pthread_cond_wait仍然要阻塞。

pthread_mutex_lock();   

pthread_cond_signal();   

pthread_mutex_unlock();

條件變數為什麼要與pthread_mutex一起使用呢?這是為了應對執行緒1在呼叫pthread_cond_wait()但執行緒1還沒有進入wait cond的狀態的時候,此時執行緒2呼叫了cond_singal的情況。 如果不用mutex鎖的話,這個cond_singal就丟失了。加了鎖的情況是,執行緒2必須等到mutex被釋放(也就是 pthread_cod_wait()釋放鎖並進入wait_cond狀態,此時執行緒2上鎖)的時候才能呼叫cond_singal。

示例**:

#include #include #include #include int done = 0;

pthread_mutex_t mutex = pthread_mutex_initializer;

pthread_cond_t cond = pthread_cond_initializer;

void thread_exit()

void *child(void *args)

void thread_join()

printf("2222222\n");

pthread_mutex_unlock(&mutex);}

int main()

互斥鎖與條件變數

最近複習湯小丹的 計算機作業系統 西安電子科技大學出版社,第三版 程序 執行緒同步章節時,發現乙個疑問。在講程序同步時,提到了兩類方法 訊號量機制和管程機制。訊號量機制又包括四種 整型訊號量 記錄型訊號量 and型訊號量 訊號量集。如果採用整型訊號量或記錄型訊號量,則在共享多個資源時,可能出現程序死...

互斥鎖與條件變數

互斥鎖用於保護臨界區,使得任何時刻只有乙個執行緒在執行其中的 確切的說,互斥鎖用於保護多個執行緒或多個程序分享的共享資料。posix互斥鎖被宣告為具有pthread mutex t資料型別的變數。若互斥鎖變數是靜態分配的,則初始化為 static pthread mutex t lock pthre...

互斥鎖與條件變數

pthread cond wait總和乙個互斥鎖結合使用。在呼叫pthread cond wait前要先獲取鎖。pthread cond wait函式執行時先自動釋放指定的鎖,然後等待條件變數的變化。在函式呼叫返回之前,自動將指定的互斥量重新鎖住。int pthread cond signal pt...