notify和unlock的順序

虛假喚醒

即使沒有線程向條件變量發出信號,線程也可能從等待狀態中喚醒。

注:虛假喚醒很容易被人誤解爲:如果有多個消費者,這些消費者可能阻塞在同一位置。當生產者通知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

發佈了190 篇原創文章 · 獲贊 72 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章