- mutex[meta header]
- std[meta namespace]
- class template[meta id-type]
- cpp11[meta cpp]
namespace std {
template <class Mutex>
class lock_guard;
}
lock_guard
は、ミューテックスのlock()
/unlock()
処理をコンストラクタとデストラクタで確実に実行するためのクラスである。このクラスは通常、メンバ変数もしくはグローバル変数としてもつミューテックスオブジェクトに対し、ブロックスコープの先頭でlock()
を呼び出し、同ブロックスコープを抜ける際にunlock()
を確実に呼び出すために使用される。この手法は、Scoped Locking Patternとして知られている。
テンプレートパラメータMutex
は、lock()
/unlock()
メンバ関数を持つあらゆるミューテックスクラスを扱うためのものである。ミューテックス型をパラメータ化するScoped Locking手法は、Strategized Locking Patternとして知られている。
lock_guard
は、非常にシンプルな機能「コンストラクタでロックを取得/ロック済みミューテックスを受け取る」「デストラクタでロックを手放す」しか提供しないが、使用メモリや実行時処理に関するオーバーヘッドは小さい(ほぼゼロ)。一方で、より高度なミューテックスのロック操作が必要な場合はunique_lock
を利用する。
なお、C++17では複数のミューテックスを正しく簡便に扱うためにscoped_lock
が追加されている。
名前 | 説明 | 対応バージョン |
---|---|---|
(constructor) |
コンストラクタ | C++11 |
(destructor) |
デストラクタ | C++11 |
operator=(const lock_guard&) = delete |
代入演算子 | C++11 |
名前 | 説明 | 対応バージョン |
---|---|---|
mutex_type |
ミューテックス型Mutex |
C++11 |
#include <iostream>
#include <thread>
#include <mutex>
// std::coutへのアクセスを排他的にする
std::mutex print_mtx_;
void safe_print(int x)
{
std::lock_guard<std::mutex> lock{print_mtx_};
std::cout << "value:" << x << std::endl;
}
#include <random>
void sleep_random()
{
std::random_device seed_gen;
std::mt19937 engine{seed_gen()};
std::uniform_int_distribution<int> dist{1, 10};
int sleep_ms = dist(engine);
std::this_thread::sleep_for(std::chrono::milliseconds{sleep_ms});
}
int main()
{
std::thread t1([]{
for (int i = 0; i < 5; i++) {
safe_print(i);
sleep_random();
}
});
std::thread t2([]{
for (int i = 0; i < 5; i++) {
safe_print(5 + i);
sleep_random();
}
});
t1.join();
t2.join();
}
- std::lock_guard[color ff0000]
value:5
value:0
value:6
value:1
value:2
value:3
value:7
value:4
value:8
value:9
- C++11
- Clang: 14 [mark verified]
- GCC: 4.7.0 [mark verified]
- ICC: ??
- Visual C++: 2012 [mark verified], 2013 [mark verified], 2015 [mark verified]