C++多线程:互斥变量 std::mutex
文章目錄
- 描述
- 成員函數(shù)
- 總結(jié)
描述
- 頭文件
<mutex> - 使用
std::mutex <variable> - 簡(jiǎn)介
mutex是一種多線程變成中的同步原語,它能夠讓共享數(shù)據(jù)不被多個(gè)線程同時(shí)訪問,它不支持遞歸得對(duì)互斥對(duì)象上鎖 - 特點(diǎn)
- 用方線程從它成功調(diào)用 lock 或 try_lock 開始,到它調(diào)用 unlock 為止占有 mutex
- 線程占有 mutex 時(shí),所有其他線程若試圖要求 mutex 的所有權(quán),則將阻塞(對(duì)于 lock 的調(diào)用)或收到 false 返回值(對(duì)于 try_lock )
- 調(diào)用方線程在調(diào)用 lock 或 try_lock 前必須不占有 mutex ,否則無法獲取<mutex>變量
成員函數(shù)
-
構(gòu)造函數(shù)
std::mutex::mutexconstexpr mutex() noexcept;(1) mutex( const mutex& ) = delete;(2)(1)構(gòu)造mutex實(shí)例,
mutex實(shí)例構(gòu)造完成之后是處于unlocked狀態(tài)
(2)mutex的拷貝構(gòu)造函數(shù)是不存在的 -
std::mutex::~mutex析構(gòu)函數(shù)
銷毀互斥變量
若互斥為任何線程占有,或若任何線程在保有任何互斥的所有權(quán)時(shí)終止,則行為未定義 -
賦值運(yùn)算符,不存在
-
std::mutex::lock
鎖定互斥。若另一線程已鎖定互斥,則到 lock 的調(diào)用將阻塞執(zhí)行,直至獲得鎖
錯(cuò)誤發(fā)生時(shí)拋出 std::system_error ,包括底層操作系統(tǒng)阻止 lock 滿足其規(guī)定的錯(cuò)誤。在拋出任何異常的情況下,不鎖定互斥。所以,直接使用mutex的lock成員是無處法處理異常的情況。#include <iostream> #include <chrono> #include <thread> #include <mutex>int g_num = 0; // protected by g_num_mutex 共享數(shù)據(jù) std::mutex g_num_mutex;void slow_increment(int id) {for (int i = 0; i < 3; ++i) {g_num_mutex.lock();++g_num;std::cout << id << " => " << g_num << '\n';g_num_mutex.unlock();//chrono是C++的時(shí)間庫,提供1s線程的休眠std::this_thread::sleep_for(std::chrono::seconds(1));} }int main() {//0號(hào)線程和1號(hào)線程交叉執(zhí)行對(duì)全局變量g_num對(duì)累加操作,執(zhí)行完成之后sleep 1秒std::thread t1(slow_increment, 0);std::thread t2(slow_increment, 1);t1.join();t2.join(); }輸出如下
0 => 1 1 => 2 0 => 3 1 => 4 0 => 5 1 => 6 -
std::mutex::try_lock
嘗試鎖定互斥。立即返回。成功獲得鎖時(shí)返回 true ,否則返回 false。
若此操作返回 true ,則同一互斥上的先前 unlock() 操作同步于(定義于 std::memory_order )它。注意若此操作返回 false ,則先前的 lock() 不與之同步#include <chrono> #include <mutex> #include <thread> #include <iostream> // std::coutstd::chrono::milliseconds interval(100);std::mutex mutex; int job_shared = 0; // 兩個(gè)線程都能修改 'job_shared',// mutex 將保護(hù)此變量int job_exclusive = 0; // 只有一個(gè)線程能修改 'job_exclusive'// 不需要保護(hù)// 此線程能修改 'job_shared' 和 'job_exclusive' void job_1() {std::this_thread::sleep_for(interval); // 令 'job_2' 持鎖while (true) {// 嘗試鎖定 mutex 以修改 'job_shared'if (mutex.try_lock()) {std::cout << "job shared (" << job_shared << ")\n";mutex.unlock();return;} else {// 不能獲取鎖以修改 'job_shared'// 但有其他工作可做++job_exclusive;std::cout << "job exclusive (" << job_exclusive << ")\n";std::this_thread::sleep_for(interval);}} }// 此線程只能修改 'job_shared' void job_2() {mutex.lock();std::this_thread::sleep_for(5 * interval);++job_shared;mutex.unlock(); }int main() {/*可以看到j(luò)ob1中的實(shí)現(xiàn),使用的是try_lock獲取鎖,因?yàn)閯傞_始job1線程會(huì)進(jìn)行100毫秒的休眠,所以cpu會(huì)先去執(zhí)行job2,但是job2使用的是lock成員所以在job2中sleep 500毫秒的過程中執(zhí)行job1時(shí)try_lock返回false,則執(zhí)行exclusive輸出.當(dāng)job2獲取不到鎖,job1休眠結(jié)束之后釋放鎖,則job1重新獲取鎖成功*/std::thread thread_1(job_1);std::thread thread_2(job_2);thread_1.join();thread_2.join(); }輸出如下
job exclusive (1) job exclusive (2) job exclusive (3) job exclusive (4) job shared (1) -
std::mutex::unlock解鎖mutex實(shí)例
使用前提是當(dāng)前線程必須被mutex的實(shí)例鎖定,否則改函數(shù)的調(diào)用是未定義的
注意,當(dāng)前成員與lock()成員,一般不直接調(diào)用,因?yàn)閷?duì)異常情況的處理并不友好(程序鎖定期間發(fā)生異常,進(jìn)程就直接退出),所以一般與std::unique_lock 與 std::lock_guard 管理排他性鎖 一起使用
具體使用實(shí)例可以參考如上兩個(gè)代碼。
總結(jié)
mutex互斥變量,并提供來了獨(dú)占鎖特性。為C++提供了多線程訪問共享數(shù)據(jù)的保護(hù)措施,同時(shí)引入了像unique_lock和lock_gurad異常處理鎖機(jī)制來規(guī)避mutex的成員處理異常情況的不足。
總結(jié)
以上是生活随笔為你收集整理的C++多线程:互斥变量 std::mutex的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字幕左下角这个怎么弄
- 下一篇: C++ 多线程:互斥对象 lock_gu