以下是一些將從多個線程調用的代碼片段。每個線程的謂詞std::condition_variable::wait
會有所不同,但它不會改變問題。訂購std :: unique_lock <std::mutex>後多重線程如何重新獲取std :: condition_variable :: notify_all
std::unique_lock<std::mutex> lock{connection_mutex};
cv.wait(lock,
[conn = shared_from_this()]
{
return conn->connection_is_made();
}
);
//do some stuff
lock.unlock();
閱讀此當條件變量被通知,超時期滿,或發生虛假喚醒,該線程被喚醒,並且互斥原子重新獲取。如果喚醒是虛假的,那麼線程應該檢查條件並重新等待。
從這個我明白,lock
將被鎖定,比謂詞拉姆達將被檢查,如果返回true
的lock
將保持鎖定狀態,我可以繼續做這個互斥鎖的保護下一些東西。當std::condition_variable
被notify_one()
通知成員函數時,它是非常有意義的。
但是當std::condition_variable
被notify_all()
通知時會發生什麼?我不能在文檔中找到所有線程是否被喚醒,而不是「等待在一行中」來鎖定互斥鎖,然後檢查謂詞返回的內容,或者可能還有其他操作。
編輯:我看到下面的評論後開始思考一點。 std::condition_variable::wait
預計std::unique_lock
作爲第一個參數,當std::condition_variable::wait
在通知後被喚醒時 - std::unique_lock
將被重新獲取。現在,如果多個線程正在等待相同的通知,那麼當notify_all()
最終被調用特定的std::condition_variable
時,只有1個線程將能夠鎖定互斥鎖,並且所有其他線程將回到休眠狀態。因此,除非效率較低,否則,如果它具有與notify_one()
相同的效果,則根本沒有看到具有notify_all()
成員函數的任何點。我的意思是,如果必須重新獲取互斥量爲 的線程才能通過std::condition_variable::wait
,那麼所有等待的線程都不能同時執行。
如果您詢問通知訂單,那麼這可能會有所幫助:http:// stackoverflow。com/questions/15912322/condition-variable-deadlock – didiz
感謝您的回答,但在這種情況下,我並不擔心從不接收notify_all()信號。我只想知道多個線程在等待相同的condition_variable時是如何工作的,然後通過notify_all()接收通知,然後嘗試獲取相同的互斥鎖。 – etrusks
這取決於操作系統調度程序。您無法知道哪個線程首先獲取互斥鎖。 – 1000ml