namespace std {
class shared_timed_mutex;
}
概要
shared_timed_mutex
クラスは、Readers–writer lockパターンをサポートするミューテックスクラスである。
このパターンは、「複数のユーザーによる読み込みと、単一ユーザーによる書き込み」の排他制御を効率的に行う、というものである。
このミューテックスクラスのロック取得方法は2種類ある。
lock()
/unlock()
メンバ関数:書き込み用のロックを取得するlock_shared()
/unlock_shared()
メンバ関数:読み込み用のロックを取得する
このクラスは、デストラクタで自動的にロックを手放すことはしない。そのため、以下の補助クラスを使用して、デストラクタで自動的にロックを手放す。
lock_guard
クラス/unique_lock
クラス:書き込み用のロックを自動的に手放すshared_lock
:読み込み用のロックを自動的に手放す
このクラスは、shared_mutex
クラスの機能に加えて、タイムアウト指定の機能を持つ。
備考
- このクラスは現状、書き込みロックと読み込みロックについてのスケジューリング戦略を規定せず、カスタマイズもできない。そのため、書き込みロックがなかなか取得できない、読み込みロックがなかなか取得できないというスタベーションの問題が発生した場合に、ユーザーの状況に合わせて戦略を変更することができない。POSIXのReaders-writer lockの実装では、スケジューリングのオプションを指定できる
メンバ関数
構築・破棄
名前 | 説明 | 対応バージョン |
---|---|---|
(constructor) |
コンストラクタ | C++14 |
(destructor) |
デストラクタ | C++14 |
operator=(const shared_timed_mutex&) = delete; |
代入演算子 | C++14 |
排他の所有権
名前 | 説明 | 対応バージョン |
---|---|---|
lock |
排他ロックを取得する | C++14 |
try_lock |
排他ロックの取得を試みる | C++14 |
try_lock_for |
タイムアウトする相対時間を指定して排他ロックの取得を試みる | C++14 |
try_lock_until |
タイムアウトする絶対時間を指定して排他ロックの取得を試みる | C++14 |
unlock |
排他ロックを手放す | C++14 |
共有の所有権
名前 | 説明 | 対応バージョン |
---|---|---|
lock_shared |
共有ロックを取得する | C++14 |
try_lock_shared |
共有ロックの取得を試みる | C++14 |
try_lock_shared_for |
タイムアウトする相対時間を指定して共有ロックの取得を試みる | C++14 |
try_lock_shared_until |
タイムアウトする絶対時間を指定して共有ロックの取得を試みる | C++14 |
unlock_shared |
共有ロックを手放す | C++14 |
例
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <chrono>
std::mutex print_mtx;
void print_value(int x)
{
std::lock_guard<std::mutex> lock(print_mtx);
std::cout << x << std::endl;
}
class X {
std::shared_timed_mutex mtx_;
int count_ = 0;
public:
// 書き込み側:カウンタを加算する
void writer()
{
std::lock_guard<std::shared_timed_mutex> lock(mtx_);
++count_;
}
// 読み込み側:カウンタの値を読む
void reader()
{
int local_count;
{
std::shared_lock<std::shared_timed_mutex> lock(mtx_);
local_count = count_;
} // 共有ロックをここで手放す
print_value(local_count);
}
};
X obj;
void writer_thread()
{
for (int i = 0; i < 3; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
obj.writer();
}
}
void reader_thread()
{
for (int i = 0; i < 10; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
obj.reader();
}
}
int main()
{
// 書き込みユーザー1人
// 読み込みユーザー3人
std::thread writer1(writer_thread);
std::thread reader1(reader_thread);
std::thread reader2(reader_thread);
std::thread reader3(reader_thread);
writer1.join();
reader1.join();
reader2.join();
reader3.join();
}
67
std::this_thread::sleep_for(std::chrono::milliseconds(1));
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <chrono>
std::mutex print_mtx;
void print_value(int x)
{
std::lock_guard<std::mutex> lock(print_mtx);
std::cout << x << std::endl;
}
class X {
std::shared_timed_mutex mtx_;
int count_ = 0;
public:
// 書き込み側:カウンタを加算する
void writer()
出力例
1
1
1
2
2
2
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
バージョン
言語
- C++14
処理系
- Clang: 3.5 ✅
- GCC: 4.9 ✅
- ICC: ??
- Visual C++: 2015 ✅