1. 程式人生 > >多執行緒中的條件變數和虛假喚醒(Spurious wakeup)

多執行緒中的條件變數和虛假喚醒(Spurious wakeup)



這是因為可能會存在虛假喚醒”spurious wakeup”的情況。

也就是說,即使沒有執行緒呼叫condition_signal, 原先呼叫condition_wait的函式也可能會返回。此時執行緒被喚醒了,但是條件並不滿足,這個時候如果不對條件進行檢查而往下執行,就可能會導致後續的處理出現錯誤。 
虛假喚醒在linux的多處理器系統中/在程式接收到訊號時可能回發生。在Windows系統和JAVA虛擬機器上也存在。在系統設計時應該可以避免虛假喚醒,但是這會影響條件變數的執行效率,而既然通過while迴圈就能避免虛假喚醒造成的錯誤,因此程式的邏輯就變成了while迴圈的情況。 
注意:即使是虛假喚醒的情況,執行緒也是在成功鎖住mutex後才能從condition_wait()中返回。即使存在多個執行緒被虛假喚醒,但是也只能是一個執行緒一個執行緒的順序執行,也即:lock(mutex)   檢查/處理  condition_wai()或者unlock(mutex)來解鎖.


4. 解鎖和等待轉移(wait morphing)

解鎖互斥量mutex和發出喚醒訊號condition_signal是兩個單獨的操作,那麼就存在一個順序的問題。誰先隨後可能會產生不同的結果。如下: 
[color=red](1) 按照 unlock(mutex); condition_signal()順序, 當等待的執行緒被喚醒時,因為mutex已經解鎖,因此被喚醒的執行緒很容易就鎖住了mutex然後從conditon_wait()中返回了。