淺談C++11中的幾種鎖
互斥鎖(mutex)
可以避免多個線程在某一時刻同時操作一個共享資源,標(biāo)準(zhǔn)C++庫提供了std::unique_lock類模板,實現(xiàn)了互斥鎖的RAII慣用語法:
eg:
std::unique_lock<std::mutex> lk(mtx_sync_);
條件鎖(condition_variable)
條件鎖就是所謂的條件變量,某一個線程因為某個條件未滿足時可以使用條件變量使該程序處于阻塞狀態(tài)。一旦條件滿足了,即可喚醒該線程(常和互斥鎖配合使用),喚醒后,需要檢查變量,避免虛假喚醒。
eg:
線程1:
// wait ack { ? ? std::unique_lock<std::mutex> lk(mtx_sync_); ? ? if (!cv_sync_.wait_for(lk, 1000ms, [this](){return sync_; })) // wait for 1s ? ? { ? ? ? ? // wait failed ? ? ? ? printf("wait for notify timeout [%d].\n", cnt); ? ? ? ? return false; ? ? } ? ? else ? ? { ? ? ? ? return true; ? ? } }
線程2:
{ ?? ?std::unique_lock<std::mutex> lk(mtx_sync_); ?? ?sync_ = true; } // 通知前解鎖,可以避免喚醒線程后由于互斥鎖的關(guān)系又進入了阻塞階段 cv_sync_.notify_one();
自旋鎖(不推薦使用)
自旋鎖是一種基礎(chǔ)的同步原語,用于保障對共享數(shù)據(jù)的互斥訪問。與互斥鎖的相比,在獲取鎖失敗的時候不會使得線程阻塞而是一直自旋嘗試獲取鎖。當(dāng)線程等待自旋鎖的時候,CPU不能做其他事情,而是一直處于輪詢忙等的狀態(tài)。自旋鎖主要適用于被持有時間短,線程不希望在重新調(diào)度上花過多時間的情況。實際上許多其他類型的鎖在底層使用了自旋鎖實現(xiàn),例如多數(shù)互斥鎖在試圖獲取鎖的時候會先自旋一小段時間,然后才會休眠。如果在持鎖時間很長的場景下使用自旋鎖,則會導(dǎo)致CPU在這個線程的時間片用盡之前一直消耗在無意義的忙等上,造成計算資源的浪費。
// 用戶空間用 atomic_flag 實現(xiàn)自旋互斥 #include <thread> #include <vector> #include <iostream> #include <atomic> ? std::atomic_flag lock = ATOMIC_FLAG_INIT; ? void f(int n) { ? ? for (int cnt = 0; cnt < 100; ++cnt) { ? ? ? ? while (lock.test_and_set(std::memory_order_acquire)) ?// 獲得鎖 ? ? ? ? ? ? ?; // 自旋 ? ? ? ? std::cout << "Output from thread " << n << '\n'; ? ? ? ? lock.clear(std::memory_order_release); ? ? ? ? ? ? ? // 釋放鎖 ? ? } } ? int main() { ? ? std::vector<std::thread> v; ? ? for (int n = 0; n < 10; ++n) { ? ? ? ? v.emplace_back(f, n); ? ? } ? ? for (auto& t : v) { ? ? ? ? t.join(); ? ? } }
遞歸鎖(recursive_mutex)
recursive_mutex 類是同步原語,能用于保護共享數(shù)據(jù)免受從個多線程同時訪問。
recursive_mutex 提供排他性遞歸所有權(quán)語義:
- 調(diào)用方線程在從它成功調(diào)用 lock 或 try_lock 開始的時期里占有 recursive_mutex 。此時期間,線程可以進行對 lock 或 try_lock 的附加調(diào)用。所有權(quán)的時期在線程調(diào)用 unlock 匹配次數(shù)時結(jié)束。
- 線程占有 recursive_mutex 時,若其他所有線程試圖要求 recursive_mutex 的所有權(quán),則它們將阻塞(對于調(diào)用 lock )或收到 false 返回值(對于調(diào)用 try_lock )。
- 可鎖定 recursive_mutex 次數(shù)的最大值是未指定的,但抵達該數(shù)后,對 lock 的調(diào)用將拋出 std::system_error 而對 try_lock 的調(diào)用將返回 false 。
- 若 recursive_mutex 在仍為某線程占有時被銷毀,則程序行為未定義。 recursive_mutex 類滿足互斥 (Mutex) 和標(biāo)準(zhǔn)布局類型 (StandardLayoutType) 的所有要求。
到此這篇關(guān)于淺談C++11中的幾種鎖的文章就介紹到這了,更多相關(guān)C++11 鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++使用easyX庫實現(xiàn)三星環(huán)繞效果流程詳解
EasyX是針對C/C++的圖形庫,可以幫助使用C/C++語言的程序員快速上手圖形和游戲編程。這篇文章主要介紹了C++使用easyX庫實現(xiàn)三星環(huán)繞效果,需要的可以參考一下2022-10-10C++詳解非類型模板參數(shù)Nontype與Template及Parameters的使用
除了類型可以作為模板參數(shù),普通值也可以作為模板函數(shù),即非類型模板參數(shù)(Nontype Template Parameters)。下面讓我們一起了解一下2022-06-06