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();
}