多執行緒中條件變數使用的深入剖析

2021-09-25 10:42:07 字數 1201 閱讀 1545

參考部落格:

之前一直以為條件變數在pthread_cond_wait時會一直持有互斥量,後來看到陳碩的書上的例子,發現如果是這樣會很容易造成死鎖,因此才考慮到是自己想錯了,於是在網上搜尋了資料終於弄明白了是怎麼回事

第一點:條件變數在pthread_cond_wait狀態不持有互斥鎖

條件變數進入pthread_cond_wait可分為三個步驟:

pthread_cond_wait(&cond, &cmutex)=

可以看出,進入wait狀態時,會首先釋放互斥鎖,之後執行緒阻塞等待喚醒,釋放了鎖使得喚醒條件變數的執行緒有機會加鎖執行。在這種情況下,我們可以想到該執行緒釋放鎖之後,如果沒有執行緒搶占並傳送訊號啟用條件變數,其他消費者執行緒(與本執行緒功能一樣)就會搶占鎖,也會進入wait狀態,這樣如果長時間沒有啟用條件變數的訊號,就會有多個執行緒處於被啟用狀態。這樣乙個訊號到來就會使這多個程序搶占資源產生競爭。

第二點:互斥鎖的作用

與條件變數配套使用的互斥鎖作用有很多,首先互斥鎖保護了queue變數的臨界區,看下面**可以知道,lock加鎖解鎖中間就是queue的臨界區。

int dequeue() 

......

}

其次,互斥鎖也保護了條件變數避免受到驚群影響

多執行緒程式中,在使用條件變數前新增互斥鎖使得同一時間只有乙個執行緒獲得了鎖,其他執行緒處於未得到鎖處於阻塞狀態節省了系統資源,獲得鎖的執行緒進入pthread_cond_wait狀態並釋放鎖,接著要麼能獲得訊號並加鎖開始執行業務,要麼阻塞在wait狀態,其他執行緒搶占鎖,新增互斥鎖總能保證獲得喚醒的執行緒均在執行業務,空閒執行緒都處於阻塞狀態

另外上面說的可能存在多個執行緒處於wait狀態,這些執行緒均能接收到某個執行緒發來的pthread_cond_signal或者pthread_cond_broadcast,但是由於互斥鎖的存在,收到訊號的執行緒被喚醒後立刻搶占互斥鎖,其他收到訊號的執行緒再次被阻塞,這樣避免了驚群問題。搶占到鎖的執行緒開始處理業務,其他執行緒繼續等待訊號。

第三,條件變數為啥使用while而不是if

原因是即使沒有執行緒呼叫condition_signals,原先呼叫condition_wait的函式也有可能返回。此時執行緒被喚醒了,但是條件不滿足,如果此時不對條件進行檢查而繼續往下執行,就可能會導致後續的處理出現錯誤。

多執行緒中條件變數的使用

如果想要實現在乙個執行緒中需要一直等待某種條件被滿足的時候,該執行緒才會進行處理,這個時候可以使用條件變數的方式來實現 乙個執行緒中進行wait,另一線程中當條件滿足時發出通知notify,這樣就不需要一直進行while迴圈進行判斷條件了 例如生產者和消費者情況 include include in...

條件變數 多執行緒

最近看 unix環境高階程式設計 多執行緒同步,看到他舉例說條件變數pthread cond t怎麼用,愣是沒有看懂,只好在網上找了份 跑了跑,才弄明白 cpp view plain copy include include include pthread mutex t mutex pthread...

多執行緒的條件變數

條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起 另乙個執行緒使 條件成立 給出條件成立訊號 為了防止競爭,條件變數的使用總是和乙個互斥鎖結合在一起。1 建立和登出 條件變數和互斥鎖一樣,都有靜態動態兩種建立方式,靜態方式使用pt...