関数内でロックを取得したミューテックスを、関数の終わりで確実にロックを手放すstd::lock_guard<MutexType>
クラスがありますが、C++1zから可変個のミューテックス型およびミューテックスオブジェクトをとるstd::scoped_lock
クラスが追加されます。
std::mutex m1; std::timed_mutex m2; std::shared_timed_mutex m3; void f() { std::scoped_lock<std::mutex, std::timed_mutex, std::shared_timed_mutex> lk { m1, m2, m3 }; // ...共有リソースに対する操作... } // ここでm1, m2, m3のunlock()メンバ関数が呼ばれる
std::scoped_lock
のテンプレート引数は、1つ以上指定する必要があります。
ロック取得済みのミューテックスオブジェクトであることを指示するstd::adopt_lock
は、std::scoped_lock
のコンストラクタの最後の引数に指定します。
std::lock(m1, m2, m3); std::scoped_lock<std::mutex, std::timed_mutex, std::shared_timed_mutex> lk { m1, m2, m3, std::adopt_lock };
各ミューテックスオブジェクトに個別で「これはロック取得済み、これはロック取得していない」というような指定はできません。
std::shared_lock
クラスの方は、可変引数化の対応はありません。
参照
- N4470 Variadic
lock_guard
- N4498 Variadic
lock_guard
(Rev. 2) - P0156R0 Variadic
lock_guard
(Rev. 3) - P0156R2 Variadic
lock_guard
(Rev. 5)
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。
記事更新
- 2017年3月のドラフト仕様更新により、
std::lock_guard
の可変引数化がとりやめとなり、可変引数をとるstd::scoped_lock
クラスを新設することになりました