名前空間
変種
操作

std::shared_mutex

提供: cppreference.com
< cpp‎ | thread
 
 
スレッドサポートライブラリ
スレッド
(C++11)
this_thread 名前空間
(C++11)
(C++11)
(C++11)
相互排他
(C++11)
shared_mutex
(C++17)
汎用ロック管理
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
条件変数
(C++11)
フューチャー
(C++11)
(C++11)
(C++11)
(C++11)
 
 
ヘッダ <shared_mutex> で定義
class shared_mutex;
(C++17およびそれ以降)

shared_mutex クラスは複数のスレッドによる同時アクセスから共有データを保護するために使用できる同期プリミティブです。 排他アクセスを提供する他のミューテックス型と比べて、 shared_mutex は2レベルのアクセスを持ちます。

  • 共有 - 複数のスレッドが同じミューテックスの所有権を共有できます。
  • 排他 - 1つのスレッドだけがミューテックスを所有できます。

shared mutex は通常、読み込みスレッドは複数同時に同じリソースにデータ競合を起こさずにアクセス可能だけれども、書き込みスレッドは同時に1つしか可能でない、という状況で使われます。

shared_mutex クラスは SharedMutex および StandardLayoutType の要件をすべて満たします。

目次

[編集] メンバ型

メンバ型 定義
native_handle_type(オプション) 処理系定義

[編集] メンバ関数

ミューテックスを構築します
(パブリックメンバ関数) [edit]
ミューテックスを破棄します
(パブリックメンバ関数) [edit]
operator=
[削除]
コピー代入可能ではありません
(パブリックメンバ関数) [edit]
排他ロック
ミューテックスをロックします。 利用可能でない場合はブロックします
(パブリックメンバ関数) [edit]
ミューテックスのロックを試みます。 利用可能でない場合はリターンします
(パブリックメンバ関数) [edit]
ミューテックスのロックを解除します
(パブリックメンバ関数) [edit]
共有ロック
共有所有権のためにミューテックスをロックします。 利用可能でない場合はブロックします
(パブリックメンバ関数) [edit]
共有所有権のためにミューテックスのロックを試みます。 利用可能でない場合はリターンします
(パブリックメンバ関数) [edit]
ミューテックスの共有所有権のロックを解除します
(パブリックメンバ関数) [edit]
ネイティブハンドル
処理系定義のベースとなるネイティブハンドルオブジェクトを返します
(パブリックメンバ関数) [edit]

[編集]

#include <iostream>
#include <mutex>  // For std::unique_lock
#include <shared_mutex>
#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<std::shared_mutex> lock(mutex_);
    return value_;
  }
 
  // Only one thread/writer can increment/write the counter's value.
  void increment() {
    std::unique_lock<std::shared_mutex> lock(mutex_);
    value_++;
  }
 
  // Only one thread/writer can reset/write the counter's 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';
 
      // Note: Writing to std::cout actually needs to be synchronized as well
      // by another std::mutex. This has been omitted to keep the example small.
    }
  };
 
  std::thread thread1(increment_and_print);
  std::thread thread2(increment_and_print);
 
  thread1.join();
  thread2.join();
}
 
// Explanation: The output below was generated on a single-core machine. When
// thread1 starts, it enters the loop for the first time and calls increment()
// followed by get(). However, before it can print the returned value to
// std::cout, the scheduler puts thread1 to sleep and wakes up thread2, which
// obviously has time enough to run all three loop iterations at once. Back to
// thread1, still in the first loop iteration, it finally prints its local copy
// of the counter's value, which is 1, to std::cout and then runs the remaining
// two loop iterations. On a multi-core machine, none of the threads is put to
// sleep and the output is more likely to be in ascending order.

出力例:

123084176803584 2
123084176803584 3
123084176803584 4
123084185655040 1
123084185655040 5
123084185655040 6

[編集] 関連項目

タイムアウト付きのロックを実装する共有可能な相互排他機能を提供します
(クラス) [edit]