std::shared_mutex
來自 cppreference.com
定義於標頭檔案 <shared_mutex> |
||
class shared_mutex; |
(C++17 起) | |
shared_mutex
類是一個同步原語,可用於保護共享資料,防止其被多個執行緒同時訪問。與其他實現獨佔訪問的互斥體型別不同,shared_mutex 具有兩種訪問級別:
- 共享 - 多個執行緒可以共享同一個互斥體的所有權。
- 獨佔 - 只有一個執行緒可以擁有互斥體。
如果一個執行緒獲得了獨佔鎖(透過lock、try_lock),則其他任何執行緒都無法獲得該鎖(包括共享鎖)。
如果一個執行緒獲得了共享鎖(透過lock_shared、try_lock_shared),則其他任何執行緒都無法獲得獨佔鎖,但可以獲得共享鎖。
只有當沒有任何執行緒獲得獨佔鎖時,多個執行緒才能獲得共享鎖。
在一個執行緒內,一次只能獲取一個鎖(共享或獨佔)。
共享互斥體在以下情況下特別有用:共享資料可以被任意數量的執行緒同時安全讀取,但只有當沒有其他執行緒同時讀取或寫入時,執行緒才能寫入相同的資料。
shared_mutex
類滿足SharedMutex和StandardLayoutType的所有要求。
目錄 |
[編輯] 成員型別
成員型別 | 定義 |
native_handle_type (可選*) |
實現定義 |
[編輯] 成員函式
構造互斥體 (公共成員函式) | |
銷燬互斥體 (公共成員函式) | |
operator= [已刪除] |
不可複製賦值 (公共成員函式) |
獨佔鎖定 | |
鎖定互斥體,如果互斥體不可用則阻塞 (公共成員函式) | |
嘗試鎖定互斥體,如果互斥體不可用則返回 (公共成員函式) | |
解鎖互斥體 (公共成員函式) | |
| |
以共享所有權鎖定互斥體,如果互斥體不可用則阻塞 (公共成員函式) | |
嘗試以共享所有權鎖定互斥體,如果互斥體不可用則返回 (公共成員函式) | |
解鎖互斥體(共享所有權) (公共成員函式) | |
原生控制代碼 | |
返回底層實現定義的原生控制代碼物件 (公共成員函式) |
[編輯] 示例
下面的輸出是在單核機器上生成的。當 thread1
啟動時,它第一次進入迴圈並呼叫 increment()
,然後呼叫 get()
。然而,在它將返回值列印到 std::cout 之前,排程程式將 thread1
置於休眠狀態並喚醒 thread2
,後者顯然有足夠的時間一次執行所有三個迴圈迭代。回到 thread1
,仍然在第一個迴圈迭代中,它最終將其計數器值的本地副本(即 1)列印到 std::cout
,然後執行剩餘的兩個迴圈迭代。在多核機器上,沒有執行緒被置於休眠狀態,輸出更可能是升序。
執行此程式碼
#include <iostream> #include <mutex> #include <shared_mutex> #include <syncstream> #include <thread> class ThreadSafeCounter { public: ThreadSafeCounter() = default; // Multiple threads/readers can read the counter's value at the same time. unsigned int get() const { std::shared_lock lock(mutex_); return value_; } // Only one thread/writer can increment/write the counter's value. void increment() { std::unique_lock lock(mutex_); ++value_; } // Only one thread/writer can reset/write the counter's value. void reset() { std::unique_lock lock(mutex_); value_ = 0; } private: mutable std::shared_mutex mutex_; unsigned int value_{}; }; int main() { ThreadSafeCounter counter; auto increment_and_print = [&counter]() { for (int i{}; i != 3; ++i) { counter.increment(); std::osyncstream(std::cout) << std::this_thread::get_id() << ' ' << counter.get() << '\n'; } }; std::thread thread1(increment_and_print); std::thread thread2(increment_and_print); thread1.join(); thread2.join(); }
可能的輸出
123084176803584 2 123084176803584 3 123084176803584 4 123084185655040 1 123084185655040 5 123084185655040 6
[編輯] 另請參閱
(C++14) |
提供共享互斥設施,並實現帶超時鎖 (類) |
(C++14) |
實現可移動的共享互斥量所有權包裝器 (類模板) |
(C++11) |
實現可移動的互斥體所有權包裝器 (類模板) |