為什麼條件鎖會產生虛假喚醒現象(spurious wakeup)?

時間 2021-06-07 22:20:48

1樓:BinGostar

之前我也很疑惑,但是了解了EINTR錯誤的產生和 @邱昊宇 的回答後,感覺虛假喚醒與訊號處理的機制有關

EINTR的產生:

當乙個慢系統呼叫(read, write 等)被阻塞時,此時外部產生訊號,然後捕獲處理訊號,處理函式返回,這個系統呼叫不再阻塞而是被中斷,返回錯誤(EINTR)

訊號處理的過程:

1)程式從核心態返回使用者空間之前,會檢查是否有訊號遞達

2)程式進入使用者態,執行訊號函式(如果有訊號),完成後再經過系統呼叫(sigreturn)進入核心態

3)如果沒有新的訊號遞達,返回使用者態

我的想法(章口就來):

當乙個程序的系統呼叫被阻塞進入睡眠狀態時(TASK_INTERRUPTIBLE),訊號產生將程序變成可執行狀態。該程序被排程執行(上述步驟 1,2,3),當返回使用者空間後(第3步末尾),因為程序不是睡眠狀態,上述的阻塞呼叫直接返回,錯誤EINTR產生。

所以需要使用者去判斷去判斷是由於訊號中斷導致的喚醒,還是訊號通知導致的喚醒。

不知道對不對???

2樓:消失的無意識

這個問題其實很好理解

從wait函式中返回的條件有二,根據順序為A,從掛起狀態中被喚醒

B,獲得cond的鎖

如果條件變數被notify

有多個執行緒同時同時從掛起狀態中被喚醒,此時他們會爭奪cond的鎖第乙個成功獲得鎖的執行緒在臨界區中讀取cond,並決定是繼續wait,還是執行他的工作,選擇後者可能會修改cond的狀態

因此後續獲得鎖的執行緒必須確認前面的執行緒是否修改了cond所以std::condition_variant有notify_one和notify_all,分別對應所有的執行緒都在等同乙個cond或存在多個cond關聯到同乙個條件變數上

與std::try_lock不同,條件變數很好地解決了執行緒的等待問題,不用頻繁地爭奪鎖

3樓:

這個查一下 wikipedia 就好了,https://en.m.wikipedia.org/wiki/Spurious_wakeup

按照裡面的說法,異常喚醒和多核處理器有關係,是底層實現的問題,所以試圖在應用層解釋都是沒有意義的

4樓:邱昊宇

舉個例子來說:

pthread 的條件變數等待 pthread_cond_wait 是使用阻塞的系統呼叫實現的(比如 Linux 上的 futex),這些阻塞的系統呼叫在程序被訊號中斷後,通常會中止阻塞、直接返回 EINTR 錯誤。

同樣是阻塞系統呼叫,你從 read 拿到 EINTR 錯誤後可以直接決定重試,因為這通常不影響它本身的語義。而條件變數等待則不能,因為本執行緒拿到 EINTR 錯誤和重新呼叫 futex 等待之間,可能別的執行緒已經通過 pthread_cond_signal 或者 pthread_cond_broadcast發過通知了。

所以,虛假喚醒的乙個可能性是條件變數的等待被訊號中斷。

不過,把等待放到迴圈裡的另乙個原因是還可能有這樣的情況(有人覺得它是虛假喚醒的一種,有人覺得不是):明明有對應的喚醒,但條件不成立。這是因為可能由於執行緒排程的原因,被條件變數喚醒的執行緒在本執行緒內真正執行「加鎖並返回」前,另乙個執行緒插了進來,完整地進行了一套「拿鎖、改條件、還鎖」的操作。

比如 Windows 下 SleepConditionVariableCS 的文件中就明確指出了可能出現這種情況。(pthread 裡的情況則有點區別,人家的 pthread_cond_signal 本來就可能喚醒多個正在等待的執行緒。)

台灣普通話裡面為什麼會產生連音現象?

Daniel 乙個猜想,不一定對。多數台灣人講的國語的跟北京人講的普通話之間有種差別,就是在發陽聲韻時,尤其是前鼻音的陽聲韻,北京人傾向於將其發成對應的近音結尾的 鼻化的音節,例如親這個字,北京人往往把它念成 ij 不存在成阻的 n 韻尾 而多數台灣人不是外省人或外省人的後代,他們的母語是泉漳混合語...

為什麼會覺得這個世界很虛假?

小胖哥哥 哦,如果是突然感覺,那麼就對了。不是這個世界虛假,而是你突然覺得自己的生活不夠充實。空虛人容易對現狀不滿,越不滿就越容易對社會越排斥。日本有個案例,寬鬆學習下的一代人更容易得抑鬱症,更容易變宅男宅女,而在私立學校嚴格教育下的人精神面貌會更好。所以,這個事實告訴我們,少年,學習使你快樂啊,你...

java偏向鎖,輕量級鎖與重量級鎖為什麼會相互膨脹

麒麟改bug 1.偏向鎖 在鎖物件的物件頭中記錄下當前獲取到該鎖的執行緒ID,該執行緒下次如果來獲取該鎖就可以直接獲取到了 螞蟻一面面試真題解析 配套筆記 2.輕量級鎖 由偏向鎖公升級來,當個執行緒獲取到鎖後,此時這把鎖是偏向鎖,此時如果有第個執行緒來競爭鎖,偏向鎖就會公升級為輕量級鎖,之所以叫輕量...