使用例は2つあります。
A. 2 つのスレッドのキューへのアクセスを同期したいです。
B. 2 つのスレッドのキューへのアクセスを同期し、条件変数を使用します。これは、スレッドの 1 つが、他のスレッドによってキューにコンテンツが格納されるのを待機するためです。
AIの使用例については、コード例を参照してください。std::lock_guard<>
ユースケースBIについては、コード例を参照してください。std::unique_lock<>
。
これら 2 つの違いは何ですか? また、どのユースケースでどちらを使用すればよいですか?
ベストアンサー1
違いは、 をロックおよびロック解除できることですstd::unique_lock
。std::lock_guard
は構築時に 1 回だけロックされ、破壊時にロック解除されます。
std::unique_lock
したがって、ユースケース Bでは、条件変数に が必ず必要です。ケース A では、ガードを再ロックする必要があるかどうかによって異なります。
std::unique_lock
他にも、ミューテックスをすぐにロックせずにRAIIラッパーを構築できる機能があります(ここ)。
std::lock_guard
便利な RAII ラッパーも提供していますが、複数のミューテックスを安全にロックすることはできません。限定されたスコープのラッパーが必要な場合、たとえばメンバー関数が必要な場合に使用できます。
class MyClass{
std::mutex my_mutex;
void member_foo() {
std::lock_guard<mutex_type> lock(this->my_mutex);
/*
block of code which needs mutual exclusion (e.g. open the same
file in multiple threads).
*/
//mutex is automatically released when lock goes out of scope
}
};
chmike さんの質問を明確にすると、デフォルトではstd::lock_guard
と はstd::unique_lock
同じです。したがって、上記のケースでは、std::lock_guard
を に置き換えることができますstd::unique_lock
。ただし、std::unique_lock
のオーバーヘッドが少し大きくなる可能性があります。
最近では(C++17以降)、std::scoped_lock
の代わりにstd::lock_guard
。