I'm trying to figure out the scope of mutexes and mutex lock_guard
and no one has been able to explain it to me. Consider the following c++ code:
void somefunction
{
std::lock_guard<std::mutex> guard(mutex1);
variable1++;
std::lock_guard<std::mutex> guard(mutex2); //what if I took this mutex out?
variable2++;
/*
long block of code
*/
variable3++;
}
I'm trying to determine what the rule for what a mutex lock_guard
protects. For example, in the current code does mutex2
protect variable3
? What if we took out mutex2
? Does mutex1
then protect variable1
variable2
and variable3
? How do I know what the mutex protects? Thank you
The std::lock_guard
does not guard the variables. The std::lock_guard
guards the mutex by ensuring that lock()
and unlock()
are called exactly once.
It behaves like
void somefunction
{
mutex1.lock();
variable1++;
mutex2.lock(); //what if I took this mutex out?
variable2++;
/*
long block of code
*/
variable3++;
// I assume the long code block has no local variables whose destructors would modify the protected variables,
// the destructors of local variables happen after the manual method calls.
mutex2.unlock(); //what if I took this mutex out?
mutex1.unlock();
}
The mutexes are responsible to guard (synchronize) the access to a shared resource (variables or a critical section or something else).
It is a general problem that it may not be obvious which data is protected by which mutex as the mutex and variables are not directly bound to each other. It depends on the use case, but in some cases std::atomic
can be a better solution, here it is obvious which variables are protected by what (the atomic variables protect themselves).
Note: In this context I would assume that mutex1
belongs to variable1
and mutex2
belongs to variable2
, variable3
is unclear
As for //what if I took this mutex out?
If something else accesses variable2
or variable3
while holding mutex2
but not mutex1
, then there can be a data race.
If every other access to variable2
and variable3
also has mutex1
locked, then mutex2
would indeed be useless and can be removed.