深入理解條件變數 虛假喚醒

2021-10-03 14:13:12 字數 1554 閱讀 9981

深入條件變數

pthread_cond_wait()pthread_cond_signal()的偽實現

pthread_cond_wait

(mutex,cond)

// 競爭失敗,那麼就不加入等待佇列了,相當於直接(喚醒)

else

pthread_mutex_unlock

(cond->mutex)

;// 重新鎖住傳入的互斥量

pthread_mutex_lock

(mutex);}

pthread_cond_signal

(cond)

pthread_mutex_unlock

(cond->mutex)

;}

考慮2個執行緒, a 和 b

執行緒a執行pthread_cond_wait()後,執行緒b執行pthread_cond_signal(),此時2個執行緒同時競爭互斥量cond->mutex(語句2)

執行緒a在執行完語句1後就嘗試進入等待佇列,(此時mutex被釋放,程式以為執行緒a已經被掛起,但實際上只是在嘗試進入等待佇列),

執行緒b獲得鎖cond->mutex,修改條件cond->value後,發現等待隊列為空if (cond->waiter)不成立,則釋放鎖,執行緒a獲得鎖,發現條件被改變後又釋放鎖(因為沒有加入到等待佇列,又釋放了鎖,所以看起來像被喚醒了一樣,(實際上根本沒加入到等待佇列中

所以被pthread_cond_wait()喚醒不一定要加入到等待佇列中,具體看pthread_cond_signal()執行的時機

執行緒a獲得鎖cond->mutex,然後將自己加入到等待佇列中,釋放鎖後掛起,然後執行緒b獲得鎖,if (cond->waiter)成立,將執行緒a從等待佇列中移出(即喚醒)

3個執行緒 a b c

執行緒a先獲得鎖,那麼還是先加入到等待佇列中,然後執行緒b在喚醒乙個,執行緒c仍在等待佇列中

執行緒b先獲得鎖,修改條件,並且把執行緒c喚醒了,釋放鎖後,執行緒a把自己"喚醒了",

所以說pthread_cond_signal()至少能喚醒乙個等待該條件的執行緒

解決方法

pthread_mutex_lock

(&lock)

;while

(condvar ==0)

// 喚醒之後再次檢查條件

pthread_cond_wait

(&cond,

&lock)

;pthread_mutex_unlock

(&lock)

;

條件變數之虛假喚醒

接下來,給出 pthread cond wait 和 pthread cond signal 的偽 參考man pthread cond signal 語句後面的編號代表時間上的執行順序。pthread cond wait mutex,cond else pthread mutex lock mut...

條件變數之虛假喚醒

如有錯誤請及時指正!3.如何避免虛假喚醒 當我們使用互斥量 mutex 與條件變數 condition variable 進行多執行緒同步時有可能會產生虛假喚醒現象,那麼究竟什麼是虛假喚醒,它會在什麼情況下被觸發,什麼情況下無需考慮虛假喚醒,如何避免?linux幫助中有提到 在多核處理器下,pthr...

條件變數 虛假喚醒 放到while迴圈的原因

linux中幫助中提到 在多核處理器下,pthread cond signal可能會啟用多於乙個執行緒 阻塞在條件變數上的執行緒 結果是,當乙個執行緒呼叫pthread cond signal 後,多個呼叫pthread cond wait 或pthread cond timedwait 的執行緒返...