日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++多线程:互斥变量 std::mutex

發布時間:2023/11/27 生活经验 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++多线程:互斥变量 std::mutex 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 描述
      • 成員函數
      • 總結

描述

  • 頭文件 <mutex>
  • 使用 std::mutex <variable>
  • 簡介
    mutex是一種多線程變成中的同步原語,它能夠讓共享數據不被多個線程同時訪問,它不支持遞歸得對互斥對象上鎖
  • 特點
    • 用方線程從它成功調用 lock 或 try_lock 開始,到它調用 unlock 為止占有 mutex
    • 線程占有 mutex 時,所有其他線程若試圖要求 mutex 的所有權,則將阻塞(對于 lock 的調用)或收到 false 返回值(對于 try_lock )
    • 調用方線程在調用 lock 或 try_lock 前必須不占有 mutex ,否則無法獲取<mutex>變量

成員函數

  • 構造函數
    std::mutex::mutex

    constexpr mutex() noexcept;(1)
    mutex( const mutex& ) = delete;(2)
    

    (1)構造mutex實例,mutex實例構造完成之后是處于unlocked狀態
    (2)mutex的拷貝構造函數是不存在的

  • std::mutex::~mutex析構函數
    銷毀互斥變量
    若互斥為任何線程占有,或若任何線程在保有任何互斥的所有權時終止,則行為未定義

  • 賦值運算符,不存在

  • std::mutex::lock
    鎖定互斥。若另一線程已鎖定互斥,則到 lock 的調用將阻塞執行,直至獲得鎖
    錯誤發生時拋出 std::system_error ,包括底層操作系統阻止 lock 滿足其規定的錯誤。在拋出任何異常的情況下,不鎖定互斥。所以,直接使用mutex的lock成員是無處法處理異常的情況。

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <mutex>int g_num = 0;  // protected by g_num_mutex 共享數據
    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++的時間庫,提供1s線程的休眠std::this_thread::sleep_for(std::chrono::seconds(1));}
    }int main()
    {//0號線程和1號線程交叉執行對全局變量g_num對累加操作,執行完成之后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
    嘗試鎖定互斥。立即返回。成功獲得鎖時返回 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; // 兩個線程都能修改 'job_shared',// mutex 將保護此變量int job_exclusive = 0; // 只有一個線程能修改 'job_exclusive'// 不需要保護// 此線程能修改 '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() 
    {/*可以看到job1中的實現,使用的是try_lock獲取鎖,因為剛開始job1線程會進行100毫秒的休眠,所以cpu會先去執行job2,但是job2使用的是lock成員所以在job2中sleep 500毫秒的過程中執行job1時try_lock返回false,則執行exclusive輸出.當job2獲取不到鎖,job1休眠結束之后釋放鎖,則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實例
    使用前提是當前線程必須被mutex的實例鎖定,否則改函數的調用是未定義的
    注意,當前成員與lock()成員,一般不直接調用,因為對異常情況的處理并不友好(程序鎖定期間發生異常,進程就直接退出),所以一般與std::unique_lock 與 std::lock_guard 管理排他性鎖 一起使用
    具體使用實例可以參考如上兩個代碼。

總結

mutex互斥變量,并提供來了獨占鎖特性。為C++提供了多線程訪問共享數據的保護措施,同時引入了像unique_locklock_gurad異常處理鎖機制來規避mutex的成員處理異常情況的不足。

總結

以上是生活随笔為你收集整理的C++多线程:互斥变量 std::mutex的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。