次のように、複数のミューテックスを同時にロックできるかどうか疑問に思っています。
Mutex1.Lock();
{
Mutex2.Lock();
{
// Code locked by mutex 1 and 2.
}
Mutex2.Unlock();
// Code locked by mutex 1.
}
Mutex1.Unlock();
状況によっては非常に便利です。ありがとう。
次のように、複数のミューテックスを同時にロックできるかどうか疑問に思っています。
Mutex1.Lock();
{
Mutex2.Lock();
{
// Code locked by mutex 1 and 2.
}
Mutex2.Unlock();
// Code locked by mutex 1.
}
Mutex1.Unlock();
状況によっては非常に便利です。ありがとう。
std::lock
この目的のために存在するようです。
デッドロックを回避するために、デッドロック回避アルゴリズムを使用して、指定されたLockableオブジェクトlock1、lock2、...、locknをロックします。オブジェクトは、lock、try_lock、unlockの不特定の一連の呼び出しによってロックされます。ロックまたはロック解除の呼び出しで例外が発生した場合、再スローする前に、ロックされたオブジェクトに対してロック解除が呼び出されます。
C ++ 17はscoped_lock
、と同様に、RAIIスタイルでのデッドロックを防ぐ複数のミューテックスをロックするという特定の目的も提供しlock_guard
ます。
#include<mutex>
std::mutex mtx1, mtx2;
void foo()
{
std::scoped_lock lck{mtx1, mtx2};
// proceed
}
可能ですが、ロックの順序はアプリケーション全体で一貫している必要があります。そうしないと、デッドロックが発生する可能性があります(2つのスレッドが反対の順序でロックを取得する場合、各スレッドはもう一方のスレッドが一方のロックを解放するのを待機する可能性があります)。
例外の安全性のために、スコープ付きロックおよびロック解除機能を使用して、ロックが常に解放されるようにすることをお勧めします(std::lock_guard
たとえばstd::mutex
)。
std::mutex mtx1;
std::mutex mtx2;
std::lock_guard<std::mutex> mtx1_lock(mtx1);
{
std::lock_guard<std::mutex> mtx2_lock(mtx2);
{
}
}
コンパイラがこれらのC++11機能をサポートしていない場合、ブーストには同様のとがboost::mutex
ありboost::lock_guard
ます。