I'm wondering if it's possible to lock multiple mutexes at the same time, like:
Mutex1.Lock();
{
Mutex2.Lock();
{
// Code locked by mutex 1 and 2.
}
Mutex2.Unlock();
// Code locked by mutex 1.
}
Mutex1.Unlock();
It would be very useful for some situations. Thanks.
It is possible but the order of locking must be consistent throughout the application otherwise deadlock is a likely result (if two threads acquire the locks in opposite order then each thread could be waiting on the other to release one of the locks).
Recommend using a scoped lock and unlock facility for exception safety, to ensure locks are always released (std::lock_guard
with std::mutex
for example):
std::mutex mtx1;
std::mutex mtx2;
std::lock_guard<std::mutex> mtx1_lock(mtx1);
{
std::lock_guard<std::mutex> mtx2_lock(mtx2);
{
}
}
If your compiler does not support these C++11 features boost has similar in boost::mutex
and boost::lock_guard
.
std::lock
seems to exist for this purpose.
Locks the given Lockable objects lock1, lock2, ..., lockn using a deadlock avoidance algorithm to avoid deadlock.
The objects are locked by an unspecified series of calls to lock, try_lock, unlock. If a call to lock or unlock results in an exception, unlock is called for any locked objects before rethrowing.
http://en.cppreference.com/w/cpp/thread/lock
C++17 also provides scoped_lock
for the specific purpose of locking multiple mutexes that prevents deadlock in a RAII style, similar to lock_guard
.
#include<mutex>
std::mutex mtx1, mtx2;
void foo()
{
std::scoped_lock lck{mtx1, mtx2};
// proceed
}