當線程從等待已發出信號的條件變量中醒來,卻發現它等待的條件不滿足時,就會發生虛假喚醒。之所以稱為虛假,是因為該線程似乎無緣無故地被喚醒了。但是虛假喚醒不會無緣無故發生:它們通常是因為在發出條件變量信號和等待線程最終運行之間,另一個線程運行并更改了條件。線程之間存在競爭條件,典型的結果是有時,在條件變量上喚醒的線程首先運行,贏得競爭,有時它運行第二,失去競爭。
在許多系統上,尤其是多處理器系統上,虛假喚醒的問題更加嚴重,因為如果有多個線程在發出信號時等待條件變量,系統可能會決定將它們全部喚醒,將每個signal( )喚醒一個線程視為broadcast( )喚醒所有這些,從而打破了信號和喚醒之間任何可能預期的 1:1 關系。如果有 10 個線程在等待,那么只有一個會獲勝,另外 9 個會經歷虛假喚醒。
為了讓實現在處理操作系統內部的錯誤條件和競爭時具有靈活性,即使沒有發出信號,也可以允許條件變量從等待中返回,盡管目前尚不清楚有多少實現實際這樣做。在條件變量的 Solaris 實現中,如果進程發出信號,則可能會發生虛假喚醒而沒有發出條件信號;等待系統調用中止并返回EINTR。條件變量的 Linux pthread 實現保證它不會那樣做。
因為只要有競爭甚至可能在沒有競爭或信號的情況下都可能發生虛假喚醒,因此當線程在條件變量上喚醒時,它應該始終檢查它所尋求的條件是否得到滿足。如果不是,它應該回到條件變量上睡覺,等待另一個機會。