関数内でロックを取得したミューテックスを、関数の終わりで確実にロックを手放す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クラスを新設することになりました