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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 互斥

發布時間:2024/3/12 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 互斥 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

mutex

mutex 類是能用于保護共享數據免受從多個線程同時訪問的同步原語。
mutex 提供排他性非遞歸所有權語義:

  • 調用方線程從它成功調用 lock 或 try_lock 開始,到它調用 unlock 為止占有 mutex 。
  • 線程占有 mutex 時,所有其他線程若試圖要求 mutex 的所有權,則將阻塞(對于 lock 的調用)或收到 false 返回值(對于 try_lock )。
  • 調用方線程在調用 lock 或 try_lock 前必須不占有 mutex 。
  • 若 mutex 在仍為任何線程所占有時即被銷毀,或在占有 mutex 時線程終止,則行為未定義。
  • mutex 類滿足互斥體 (Mutex) 和標準布局類型 (StandardLayoutType) 的全部要求。

std::mutex 既不可復制亦不可移動。

成員類型native_handle_type(可選) 實現定義 成員函數(構造函數) 構造互斥(公開成員函數)(析構函數) 銷毀互斥(公開成員函數)operator=[被刪除] 不可復制賦值(公開成員函數) 鎖定lock 鎖定互斥,若互斥不可用則阻塞(公開成員函數)try_lock 嘗試鎖定互斥,若互斥不可用則返回(公開成員函數)unlock 解鎖互斥(公開成員函數) 原生句柄native_handle 返回底層實現定義的原生句柄(公開成員函數)

注意:通常不直接使用 std::mutex :std::unique_lock 、 std::lock_guard 或 std::scoped_lock (C++17 起)以更加異常安全的方式管理鎖定。

recursive_mutex

recursive_mutex 類是同步原語,能用于保護共享數據免受從個多線程同時訪問。
recursive_mutex 提供排他性遞歸所有權語義:

  • 調用方線程在從它成功調用 lock 或 try_lock 開始的時期里占有 recursive_mutex 。此時期間,線程可以進行對 lock 或 try_lock 的附加調用。所有權的時期在線程調用 unlock 匹配次數時結束。
  • 線程占有 recursive_mutex 時,若其他所有線程試圖要求 recursive_mutex 的所有權,則它們將阻塞(對于調用 lock )或收到 false 返回值(對于調用 try_lock )。
  • 可鎖定 recursive_mutex 次數的最大值是未指定的,但抵達該數后,對 lock 的調用將拋出std::system_error 而對 try_lock 的調用將返回 false 。

若 recursive_mutex 在仍為某線程占有時被銷毀,則程序行為未定義。 recursive_mutex 類滿足互
斥體 (Mutex) 和標準布局類型 (StandardLayoutType) 的所有要求。

成員類型native_handle_type(可選) 實現定義 成員函數(構造函數) 構造互斥(公開成員函數)(析構函數) 銷毀互斥(公開成員函數)operator=[被刪除] 不可復制賦值(公開成員函數) 鎖定lock 鎖定互斥,若互斥不可用則阻塞(公開成員函數)try_lock 嘗試鎖定互斥,若互斥不可用則返回(公開成員函數)unlock 解鎖互斥(公開成員函數) 原生句柄native_handle 返回底層實現定義的原生句柄(公開成員函數) //recursive_mutex 的使用場景之一是保護類中的共享狀態,而類的成員函數可能相互調用運行此代碼 #include <iostream> #include <thread> #include <mutex>class X {std::recursive_mutex m;std::string shared;public:void fun1() {std::lock_guard<std::recursive_mutex> lk(m);shared = "fun1";std::cout << "in fun1, shared variable is now " << shared << '\n';}void fun2() {std::lock_guard<std::recursive_mutex> lk(m);shared = "fun2";std::cout << "in fun2, shared variable is now " << shared << '\n';fun1(); // 遞歸鎖在此處變得有用std::cout << "back in fun2, shared variable is " << shared << '\n';}; };int main() {X x;std::thread t1(&X::fun1, &x);std::thread t2(&X::fun2, &x);t1.join();t2.join(); }

可能的輸出:

in fun1, shared variable is now fun1 in fun2, shared variable is now fun2 in fun1, shared variable is now fun1 back in fun2, shared variable is fun1

shared_mutex

shared_mutex 類是一個同步原語,可用于保護共享數據不被多個線程同時訪問。與便于獨占訪問的其他互斥類型不同,shared_mutex 擁有二個訪問級別:

  • 共享 - 多個線程能共享同一互斥的所有權。
  • 獨占性 - 僅一個線程能占有互斥。
  • 若一個線程已獲取獨占性鎖(通過 lock 、 try_lock ),則無其他線程能獲取該鎖(包括共享的)。

僅當任何線程均未獲取獨占性鎖時,共享鎖能被多個線程獲取(通過 lock_shared 、 try_lock_shared )。
在一個線程內,同一時刻只能獲取一個鎖(共享或獨占性)。
共享互斥體在能由任何數量的線程同時讀共享數據,但一個線程只能在無其他線程同時讀寫時寫同一數據時特別有用。
shared_mutex 類滿足共享互斥體 (SharedMutex) 和標準布局類型 (StandardLayoutType) 的所有要求。

成員類型native_handle_type(可選) 實現定義 成員函數(構造函數) 構造互斥(公開成員函數)(析構函數) 銷毀互斥(公開成員函數)operator=[被刪除] 不可復制賦值(公開成員函數) 排他性鎖定lock 鎖定互斥,若互斥不可用則阻塞(公開成員函數)try_lock 嘗試鎖定互斥,若互斥不可用則返回(公開成員函數)unlock 解鎖互斥(公開成員函數) 共享鎖定lock_shared 為共享所有權鎖定互斥,若互斥不可用則阻塞(公開成員函數)try_lock_shared 嘗試為共享所有權鎖定互斥,若互斥不可用則返回(公開成員函數)unlock_shared 解鎖互斥(共享所有權)(公開成員函數) 原生句柄native_handle 返回底層實現定義的原生句柄(公開成員函數) #include <iostream> #include <mutex> // 對于 std::unique_lock #include <shared_mutex> #include <thread>class ThreadSafeCounter {public:ThreadSafeCounter() = default;// 多個線程/讀者能同時讀計數器的值。unsigned int get() const {std::shared_lock<std::shared_mutex> lock(mutex_);return value_;}// 只有一個線程/寫者能增加/寫線程的值。void increment() {std::unique_lock<std::shared_mutex> lock(mutex_);value_++;}// 只有一個線程/寫者能重置/寫線程的值。void reset() {std::unique_lock<std::shared_mutex> lock(mutex_);value_ = 0;}private:mutable std::shared_mutex mutex_;unsigned int value_ = 0; };int main() {ThreadSafeCounter counter;auto increment_and_print = [&counter]() {for (int i = 0; i < 3; i++) {counter.increment();std::cout << std::this_thread::get_id() << ' ' << counter.get() << '\n';// 注意:寫入 std::cout 實際上也要由另一互斥同步。省略它以保持示例簡潔。}};std::thread thread1(increment_and_print);std::thread thread2(increment_and_print);thread1.join();thread2.join(); }// 解釋:下列輸出在單核機器上生成。 thread1 開始時,它首次進入循環并調用 increment() , // 隨后調用 get() 。然而,在它能打印返回值到 std::cout 前,調度器將 thread1 置于休眠 // 并喚醒 thread2 ,它顯然有足夠時間一次運行全部三個循環迭代。再回到 thread1 ,它仍在首個 // 循環迭代中,它最終打印其局部的計數器副本的值,即 1 到 std::cout ,再運行剩下二個循環。 // 多核機器上,沒有線程被置于休眠,且輸出更可能為遞增順序。

可能的輸出:

單核: 123084176803584 2 123084176803584 3 123084176803584 4 123084185655040 1 123084185655040 5 123084185655040 6 多核: 140623314495232 2 140623314495232 3 140623314495232 4 140623306102528 4 140623306102528 5 140623306102528 6

總結

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

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