1. ホーム
  2. c++

[解決済み】 std::unique_lock<std::mutex> と std::lock_guard<std::mutex> のどちらを選ぶ?

2022-04-13 17:32:46

質問

2つのユースケースを持っています。

A. 2つのスレッドのキューへのアクセスを同期させたいと思います。

B. 私は2つのスレッドのキューへのアクセスを同期させ、スレッドの1つが他のスレッドによってキューに格納されるコンテンツを待つので、条件変数を使用したいと思います。

使用例 A では、以下のコード例を参照してください。 std::lock_guard<> . ユースケース B では、次のようなコード例があります。 std::unique_lock<> .

この2つの違いは何ですか?また、どのようなユースケースでどちらを使えばいいのでしょうか?

どのように解決するのですか?

のロックとアンロックができる点が異なります。 std::unique_lock . std::lock_guard は、建設時に一度だけロックされ、破壊時にロックが解除されます。

したがって、ユースケースBの場合は、間違いなく std::unique_lock を条件変数として使用します。ケースAでは、ガードを再ロックする必要があるかどうかによります。

std::unique_lock には他の機能もあり、例えば、すぐにミューテックスをロックせずに RAII ラッパーを構築することができます ( ここで ).

std::lock_guard も便利な RAII ラッパーですが、複数の mutex を安全にロックすることはできません。これは、例えばメンバ関数のような限定されたスコープのラッパーが必要な場合に使用します。

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_guardstd::unique_lock は同じです。 ですから、上記の場合、次のように置き換えることができます。 std::lock_guardstd::unique_lock . しかし std::unique_lock は、もう少しオーバーヘッドがあるかもしれません。

なお、最近(C++17以降)は std::scoped_lock の代わりに std::lock_guard .