虛假喚醒
即使沒有線程向條件變量發出信號,線程也可能從等待狀態中喚醒。
注:虛假喚醒很容易被人誤解爲:如果有多個消費者,這些消費者可能阻塞在同一位置。當生產者通知not empty時,duque立即被第一個被喚醒的消費者清空,則後面的消費者相當於時被虛假喚醒了。
這種情況完全可以通過使用signal而非broadcast解決。signal只會喚醒某個線程,喚醒的依據爲等待線程的優先級,若優先級相同,則依據線程的等待時長。
wait( std::unique_lockstd::mutex& lock )
1.原子地解鎖 lock ,阻塞當前執行線程
2.將它添加到於 *this 上等待的線程列表。線程將在執行 notify_all() 或 notify_one() 或者虛假喚醒時被解除阻塞
3.lock 再次鎖定且 wait 退出
wait( std::unique_lockstd::mutex& lock, Predicate pred )
等價於
while (!pred()) {
wait(lock);
}
notify和unlock的順序
notify並不釋放鎖,只是告訴調用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因爲鎖還在別人手裏,別人還沒釋放。
將notify_one放在解鎖之前:
notifying thread: notify -> eventually release lock
notified thread: awaken -> attempt to acquire lock and fail -> block until lock available -> acquire lock after notifying thread releases it
在解鎖後放置notify_one:
notifying thread: notify
notified thread: awaken -> attempt to acquire lock and succeed