Why is this an issue?
Mutexes are synchronization primitives that allow to manage concurrency. It is a common situation to have to use multiple mutexes
to protect multiple resources with different access patterns.
In such a situation, it is crucial to define an order on the set of all mutexes.
This order should be strictly followed when locking mutexes.
The reverse order should be strictly followed when unlocking mutexes.
Failure in doing so can lead to deadlocks.
In C++, an easy way to make sure the unlocks are called in reverse order from the lock is to wrap the lock/unlock operations in a RAII class (since
destructors of local variables are called in reverse order of their creation).
If instead of pthread_mutex_t
you are using std::mutex
, there are other mechanisms that allow you to avoid deadlocks in
that case, see {rule:cpp:S5524}.
Noncompliant code example
pthread_mutex_t mtx1,mtx2;
void bad(void)
{
pthread_mutex_lock(&mtx1);
pthread_mutex_lock(&mtx2);
pthread_mutex_unlock(&mtx1);
pthread_mutex_unlock(&mtx2);
}
Compliant solution
pthread_mutex_t mtx1, mtx2; // if both have to be locked, mtx1 should always be locked before mtx2
void good(void)
{
pthread_mutex_lock(&mtx1);
pthread_mutex_lock(&mtx2);
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
}