深入條件變數
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獲得鎖,發現條件被改變後又釋放鎖(因為沒有加入到等待佇列,又釋放了鎖,所以看起來像被喚醒了一樣,(實際上根本沒加入到等待佇列中)
所以被執行緒a獲得鎖pthread_cond_wait()
喚醒不一定要加入到等待佇列中,具體看pthread_cond_signal()
執行的時機
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 的執行緒返...