C++/shared mutex
< C++
頭文件 <shared_mutex>是C++14提出的STL的通用的共享互斥所有權的包裝器。以共享模式鎖定關聯的shared_lock;而std::unique_lock 可用於以排他性模式鎖定。
shared_lock 類可移動,但不可複製——它滿足可移動構造 (MoveConstructible) 與可移動賦值 (MoveAssignable) 的要求,但不滿足可複製構造 (CopyConstructible) 或可複製賦值 (CopyAssignable) 。
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 返回底層實現定義的原生句柄
shared_timed_mutex 類
編輯shared_timed_mutex類實現了帶時限的讀寫鎖。
shared_timed_mutex 類滿足共享定時互斥體 (SharedTimedMutex) 和標準布局類型 (StandardLayoutType) 的所有要求。
成員函數
編輯- (構造函數)
- (析構函數)
- operator=[被刪除] 不可複製賦值
- lock 鎖定互斥,若互斥不可用則阻塞
- try_lock 嘗試鎖定互斥,若互斥不可用則返回
- try_lock_for 嘗試鎖定互斥,若互斥在指定的時限時期中不可用則返回
- try_lock_until 嘗試鎖定互斥,若直至抵達指定時間點互斥不可用則返回
- unlock 解鎖互斥
- lock_shared 為共享所有權鎖定互斥,若互斥不可用則阻塞
- try_lock_shared 嘗試為共享所有權鎖定互斥,若互斥不可用則返回
- try_lock_shared_for 嘗試為共享所有權鎖定互斥,若互斥在指定的時限時期中不可用則返回
- try_lock_shared_until 嘗試為共享所有權鎖定互斥,若直至抵達指定時間點互斥不可用則返回
- unlock_shared 解鎖互斥(共享所有權)
std::shared_lock類模板
編輯模板形參
編輯- Mutex 要鎖定的共享互斥的類型。
成員類型
編輯- mutex_type 定義為Mutex
成員函數
編輯- (構造函數)
- (析構函數) 解鎖關聯的互斥
- operator= 若佔有則解鎖互斥,然後獲得對方的所有權
- lock 鎖定關聯的互斥
- try_lock 嘗試鎖定關聯的互斥
- try_lock_for 嘗試鎖定關聯的互斥,以指定時長
- try_lock_until 嘗試鎖定關聯的互斥,直至指定的時間點
- unlock 解鎖關聯的互斥
- swap 與另一 shared_lock 交換數據成員
- release 解除關聯 mutex 而不解鎖
- mutex 返回指向關聯的互斥的指針
- owns_lock 測試鎖是否佔有其關聯的互斥
- operator bool 測試鎖是否佔有其關聯的互斥
例子
編輯#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();
}