互斥鎖和條件變數

2021-08-21 19:55:56 字數 2143 閱讀 7099

**:

mutex體現的是一種競爭,我離開了,通知你進來。

cond體現的是一種協作,我準備好了,通知你開始吧。

互斥鎖乙個明顯的缺點是它只有兩種狀態:鎖定和非鎖定。而條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補了互斥鎖的不足,它常和互斥鎖一起配合使用。使用時,條件變數被用來阻塞乙個執行緒,當條件不滿足時,執行緒往往解開相應的互斥鎖並等待條件發生變化。一旦其他的某個執行緒改變了條件變數,他將通知相應的條件變數喚醒乙個或多個正被此條件變數阻塞的執行緒。這些執行緒將重新鎖定互斥鎖並重新測試條件是否滿足。一般說來,條件變數被用來進行執行緒間的同步。

兩個執行緒操作同一臨界區時,通過互斥鎖保護,若a執行緒已經加鎖,b執行緒再加鎖時候會被阻塞,直到a釋放鎖,b再獲得鎖執行,程序b必須不停的主動獲得鎖、檢查條件、釋放鎖、再獲得鎖、再檢查、再釋放,一直到滿足執行的條件的時候才可以(而此過程中其他執行緒一直在等待該執行緒的結束),這種方式是比較消耗系統的資源的。而條件變數同樣是阻塞,還需要通知才能喚醒,執行緒被喚醒後,它將重新檢查判斷條件是否滿足,如果還不滿足,該執行緒就休眠了,應該仍阻塞在這裡,等待條件滿足後被喚醒,節省了執行緒不斷執行浪費的資源。這個過程一般用while語句實現。當執行緒b發現被鎖定的變數不滿足條件時會自動的釋放鎖並把自身置於等待狀態,讓出cpu的控制權給其它執行緒。其它執行緒 此時就有機會去進行操作,當修改完成後再通知那些由於條件不滿足而陷入等待狀態的執行緒。這是一種通知模型的同步方式,大大的節省了cpu的計算資源,減少了執行緒之間的競爭,而且提高了執行緒之間的系統工作的效率。這種同步方式就是條件變數。                                       

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

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

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

while(1)

}

這就有乙個問題,可能在剛進入休眠時,b放入元素了,但仍然需要休眠完整個10s的時間。造成不必要的延遲。當然如果不sleep,也可以,但會造成不必要的cpu開銷。使用基於條件變數的事件通知喚醒機制,就可以避免這些問題。

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

while(1)

條件變數都用互斥鎖進行保護,條件變數狀態的改變都應該先鎖住互斥鎖,pthread_cond_wait()需要傳入乙個已經加鎖的互斥鎖,該函式把呼叫執行緒加入等待條件的呼叫列表中,然後釋放互斥鎖,在條件滿足從而離開pthread_cond_wait()時,mutex將被重新加鎖,這兩個函式是原子操作。

可以消除條件發生和執行緒睡眠等待條件發生間的時間間隙。其他執行緒在獲得互斥量之前不會察覺到這種改變,因為必須鎖定互斥量才能計算條件。

總而言之,為了避免因條件判斷語句與其後的正文或wait語句之間的間隙而產生的漏判或誤判,所以用乙個mutex來保證: 對於某個cond的包括(判斷,修改)在內的任何有關操作某一時刻只有乙個執行緒在訪問。也就是說條件變數本身就是乙個競爭資源,這個資源的作用是對其後程式正文的執行權,於是用乙個鎖來保護。

這樣就關閉了條件檢查和執行緒進入休眠狀態等待條件改變這兩個操作之間的時間通道,這樣執行緒就不會有任何變化。

感覺可以總結為:條件變數用於某個執行緒需要在某種條件成立時才去保護它將要操作的臨界區,這種情況從而避免了執行緒不斷輪詢檢查該條件是否成立而降低效率的情況,這是實現了效率提高。。。在條件滿足時,自動退出阻塞,再加鎖進行操作。

以上是關於效率問題,此外互斥鎖還有乙個缺點就是會造成死鎖。

例如執行緒a和執行緒b都需要獨佔使用2個資源,但是他們都分別先佔據了乙個資源,然後又相互等待另外乙個資源的釋放,這樣就形成了乙個死鎖。

條件變數起到了阻塞和喚醒執行緒的作用,所以通常互斥鎖要和條件變數配合。

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

互斥鎖和條件變數

互斥瑣 定義 指代相互排斥,最基本的同步形式。用於保護臨界區,以保證任何時刻只有乙個執行緒或乙個程序在執行其中的 上鎖 pthread mutex lock 臨界區解鎖 pthread mutex unlock 條件變數 定義 用於等待訊號,同步的另一種手段。每乙個條件變數總有乙個互斥瑣與之關聯。等...

互斥鎖和條件變數

條件變數 執行緒最大的特點就是資源的共享性,然而資源共享中的同步問題是多執行緒程式設計的難點。互斥鎖通過鎖機制來實現執行緒間的同步。使用互斥鎖前必須進行初始化操作。初始化有兩種方式 一種是靜態賦值法,將將巨集結構常量pthread mutex initializer賦給互斥鎖,操作語句如下 pthr...

互斥鎖和條件變數

一直以來都理解錯了,不是使用條件變數再加上一對互斥鎖,而是條件變數內部引入乙個互斥鎖,其實主要還是條件變數在起作用,這樣會提高效率,看下面的例子。while true thread 2 while true pthread mutex unlock mutex 這種實現下,就算 lock 空閒,th...