引用:http://blog.csdn.net/leeds1993/article/details/52738845
什么是虛假喚醒?
舉個例子,我們現在有一個生產者-消費者隊列和三個線程。
I.1號線程從隊列中獲取了一個元素,此時隊列變為空。
II.2號線程也想從隊列中獲取一個元素,但此時隊列為空,2號線程便只能進入阻塞(cond.wait()),等待隊列非空。
III.這時,3號線程將一個元素入隊,並調用cond.notify()喚醒條件變量。
IV.處於等待狀態的2號線程接收到3號線程的喚醒信號,便准備解除阻塞狀態,執行接下來的任務(獲取隊列中的元素)。
V.然而可能出現這樣的情況:當2號線程准備獲得隊列的鎖,去獲取隊列中的元素時,此時1號線程剛好執行完之前的元素操作,返回再去請求隊列中的元素,1號線程便獲得隊列的鎖,檢查到隊列非空,就獲取到了3號線程剛剛入隊的元素,然后釋放隊列鎖。
VI.等到2號線程獲得隊列鎖,判斷發現隊列仍為空,1號線程“偷走了”這個元素,所以對於2號線程而言,這次喚醒就是“虛假”的,它需要再次等待隊列非空。
使用while()判斷的原因
在多核處理器下,pthread_cond_signal可能會激活多於一個線程(阻塞在條件變量上的線程)。結果就是,當一個線程調用pthread_cond_signal()后,多個調用pthread_cond_wait()或pthread_cond_timedwait()的線程返回。這種效應就稱為“虛假喚醒”。
注:pthread_cond_wait這個函數是單個原子操作,即這個函數的兩個動作:解鎖 && 進入block 是一個原子操作。