使用 c 11。由于 std::notify_all 會導致虛假喚醒,那么為什么保留 std::notify_all 而不是一直保留 std::notify_one 呢?順便說一句,std::notify_one 會導致虛假喚醒嗎?
詳細說明我的疑問:
當我呼叫std::condition_variable.wait/wait_for/wait_until和std::notify_XXX時,我的目的一般是為了實作執行緒同步。也就是說,更多的執行緒被阻塞等待直到另一個執行緒只通知其中一個解除阻塞。
那我可以直接呼叫notify_one來實作,但是為什么還有一個notify_all,它的目的是什么,或者notify_all適合什么情況呢?而在我的情況下,當我呼叫nitify_all時,它會喚醒所有等待的執行緒,然后只有一個執行緒真正解除阻塞,其他執行緒仍然阻塞,這叫虛假喚醒嗎?如果 notify_one 也會呼叫虛假喚醒?
uj5u.com熱心網友回復:
從/8.3void std::condition_variable::wait(std::unique_lock<std::mutex>& lock);開始
:thread.condition
notify_-one()當通過呼叫或呼叫或虛假notify_-all()發出信號時,該函式將解除阻塞。
所以呼叫notify_-one()ornotify_-all()不是先決條件。它可以在沒有任何被呼叫的情況下解除阻塞。
上面的參考來自“C 20 first post-publication draft”,但自從它首次為 C 11 撰寫以來一直保持不變。
為什么還有另一個,它的目的是什么,或者適合
notify_all什么情況?notify_all
當您希望所有等待執行緒解除阻塞時。實際情況是何時關閉。如果您在 a 中阻塞了執行緒,wait它們將永遠不會完成并且join()它們將掛起。
帶有謂詞的示例說它應該等到abortedistrue或queue.empty()is false:
bool pop_from_queue(T& item) {
std::unique_lock<std::mutex> lock(mtx);
while(queue.empty() && not aborted) cv.wait(lock);
if(aborted) return false; // time to shutdown
// else pick an item from the queue
item = std::move(queue.front());
queue.pop();
return true;
}
當需要關閉時,另一個執行緒通常會這樣做:
aborted = true; // std::atomic<bool>
cv.notify_all();
當我呼叫nitify_all時,它會喚醒所有等待的執行緒,然后只有一個執行緒真正解除阻塞,其他執行緒保持阻塞,這叫虛假喚醒嗎?
不會。虛假喚醒是隨時可能發生的喚醒。如果您呼叫notify_all,等待的執行緒將全部按順序喚醒 - 而不是虛假的。
如果 notify_one 也會呼叫虛假喚醒?
它可能會導致虛假喚醒,但這將是一個實作細節。最好的辦法是接受執行緒可能隨時喚醒的事實,并在它們喚醒時檢查謂詞。
我可以精確控制在等待執行緒中解除阻塞的位置(誰
condition_variable.wait在沒有謂詞的情況下呼叫)?
在不檢查謂詞的情況下,執行緒唯一確定的就是它醒來了。如果出于正確的原因,它現在不會。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/490821.html
上一篇:“如果派生類不虛擬繼承基類,則必須定義所有虛擬方法”。如何正確理解?
下一篇:向“輪廓”添加偏移量
