互斥元
std::mutex
std::lock_guard
實現互斥元的 RAII 慣用語法,它在構造時鎖定所給的互斥元,在析構時將互斥元解鎖,從而保證被鎖定的互斥元始終被正確解鎖
std::unique_lock
提供了lock()、try_lock()和unlock()三個成員函數,它們會調用底層互斥元上同名的成員函數去做實際的工作,并且只是更新在std::unique_lock實例內部的一個標識,來表示該實例當前實例是否擁有此互斥元(如果標識表示了該實例擁有互斥元,則析構函數必須調用unlock();如果不擁有互斥元,則一定不能調用unlock())。因此std::unique_lock對象的大小通常大于std::lock_guard對象;使用std::unique_lock時,由于需要對標識進行相應的更新或判斷在性能上會有些許損失
其靈活性還體現在可以在作用域之間轉移鎖的所有權
std::lock
待補充
加解鎖的一些未定義行為
待補充
共享互斥元
boost::shared_mutex
boost::unique_lock<boost::shared_mutex>
寫鎖
boost::shared_lock<boost::shared_mutex>
讀鎖
遞歸互斥元
std::recursive_mutex
待補充
條件變量
從概念上說,條件變量與某些事件或其他條件相關,并且一個或多個線程可以等待該條件被滿足。當某個線程已經確定條件得到滿足,它就可以通知一個或多個正在條件變量上進行等待的線程,以便喚醒它們并讓它們繼續處理
std::condition_variable
等待操作
調用wait()函數需要傳入鎖對象,以及表示正在等待的條件的判斷函數(判斷函數可以使用lambda表達式)
調用wait()函數時,其內部首先會調用所提供的判斷函數:
- 如果滿足條件(lambda返回true)則返回,當前線程繼續執行
- 如果不滿足條件,則將當前線程置于等待狀態(加入這個條件變量的等待隊列)并解鎖互斥元
當wait函數被喚醒時(其他線程調用通知或偽喚醒):
- 重新獲取互斥元(加鎖)
- 執行上面的一系列判斷及相應操作
偽喚醒
當等待線程重新獲取互斥元并檢查條件時,如果它并非直接響應另一個線程的通知,即偽喚醒
丟失通知
在wait操作的實現流程的分析中,判斷不滿足條件與之后的所有處理并非是個原子操作,因此當前線程進入等待狀態前,有可能其他線程的通知已經發出,這樣就丟失了通知。具體實例可參考:線程池學習
std::condition_variable_any
靈活性更大,所以可能會有大小、性能或者操作系統資源方面的額外代價
浙公網安備 33010602011771號