我們知道條件變量受到虛假喚醒的影響。假設我們有一個1-producer-1-consumer隊列與一個互斥鎖和條件變量同步。消費者線程被虛假喚醒。 問題是 - 消費者線程是否會錯過生產者的通知信號? 我知道這是非常不可能的..但是仍然有可能失去排隊中的最後一個元素與這種實現?如果虛假喚醒,消費者線程是否會收到condition_variable通知信號
1
A
回答
2
如果調用wait()
代碼不寫吧,它可能確實,錯過了一個醒。但那會有點不正當。通常的習慣用法是:
lock the mutex
while the condition is not satisfied
wait on the condition variable
信令螺紋信令之前應該鎖定互斥:
lock the mutex
signal the condition variable
等待條件變量解鎖用於等待的持續時間互斥。但是等待調用返回時,互斥鎖將被鎖定。所以在一個虛假的喚醒中,等待線程將持有該互斥體直到它恢復等待。當等待的線程持有互斥量時,信號線程不能發信號通知條件變量。當等待的線程實際等待時,互斥體被解鎖,並且信號線程可以繼續併發出信號;等待線程將獲得信號,一旦信號線程釋放互斥量,等待線程將恢復執行。
所以,不,正確的代碼不會錯過任何信號。但是,如果等待線程在檢查其狀態的過程中釋放互斥鎖並重新獲取它,則信號可能在等待線程調用等待之前發生,並且信號將丟失。不要這樣做。 < g>
+0
「當等待的線程持有互斥鎖時,信號線程不能發信號通知條件變量。」 - 那就是我錯過的。謝謝! – Sergei
1
虛假喚醒意味着它可能會虛假地喚醒,然後不得不繼續等待。
它完全沒有提到錯過事件的可能性,因爲如果這是真的,那將是沒有用的。
此鏈接提供簡歷的詳細解釋和wait方法:
https://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables
// print a starting message
{
std::unique_lock<std::mutex> locker(g_lockprint);
std::cout << "[logger]\trunning..." << std::endl;
}
// loop until end is signaled
while(!g_done)
{
std::unique_lock<std::mutex> locker(g_lockqueue);
g_queuecheck.wait(locker, [&](){return !g_codes.empty();});
// if there are error codes in the queue process them
while(!g_codes.empty())
{
std::unique_lock<std::mutex> locker(g_lockprint);
std::cout << "[logger]\tprocessing error: " << g_codes.front() << std::endl;
g_codes.pop();
}
}
相關問題
- 1. 忽略虛假喚醒,condition_variable :: wait_for
- 2. 塊和喚醒消費者線程/
- 3. 什麼是boost :: condition_variable :: timed_wait()返回虛假喚醒?
- 4. 信號喚醒線程
- 5. std :: condition_variable - 通知一次,但等待線程被喚醒兩次
- 6. 線程是否存在虛假喚醒的相應互斥量?
- 7. 哪個線程會通知喚醒?
- 8. 生產者 - 消費者模式:喚醒UI線程
- 9. 虛假喚醒會影響Thread.sleep嗎?
- 10. C#Monitor.Wait()會遭受虛假喚醒嗎?
- 11. 虛假喚醒會影響Future.get()嗎?
- 12. Java:信號量:生產者消費者:線程和線程組
- 13. EventWaitHandle是否必須處理虛假喚醒?
- 14. 是否正在等待發生虛假喚醒的事件?
- 15. 消費者生產者多線程消費者不會消逝
- 16. 在實踐中發生虛假喚醒
- 17. 虛假喚醒後的互斥狀態
- 18. 爲什麼pthread_cond_wait有虛假喚醒?
- 19. 真的發生虛假喚醒嗎?
- 20. 收集消費者信息
- 21. 通過信號喚醒std :: getline
- 22. 如何觸發Linux應用程序中的虛假喚醒?
- 23. 如何在收到通知時喚醒屏幕?
- 24. 由於虛假喚醒,Semaphore.acquire()會拋出InterruptedException嗎?
- 25. 生產者 - 消費者線程間通信
- 26. Java生產者 - 消費者:生產者不「通知()」消費者
- 27. 穿戴者是否在頻帶SDK中暴露/喚醒信息?
- 28. 如何在收到2個數據包後喚醒線程
- 29. 發信號通知線程
- 30. 接收到通知時的喚醒屏幕
_「消費者線程是否會錯過來自生產者的通知信號?」_爲什麼要這樣?這就是爲什麼有一個與cv一起使用的互斥體。你可以向你展示一個[MCVE]的內容嗎? –
afaik條件變量的整點是處理虛假喚醒的情況 – user463035818