In my answer, I assume you are using std::mutex and not your own custom class!
Essentially, the compiler cannot optimize away the second if
.
Well, if the compiler could somehow determine that x
cannot be changed (legally), it might remove the check but clearly, this is not the case here. A compiler can only do optimization if the resulting program works AS-IF.
In C++ 11 and later, a mutex is a barrier. So if a variable is properly protected by a mutex, you would read the expected value. However, it you forgot to put some mutex at appropriate location, then the behavior will be undefined.
Here, as your first check is a read, you might have a problem, if x
can again become true
one after being set once to false
.
Memory model
C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?
I highly recommend reading the book C++ Concurrency in Action, Practical Multithreading by Anthony Williams. It would help a lot understanding modern C++ multithreading.
In your code, do you need to protect fire1
and fire2
by the mutex? Calling a function can be dangerous if that function also wait for a mutex
as it can cause deadlocks. Also, the lock
might be effective longer than required. If you only need to ensure that fire1
is not called if fire2
is called, then a std::atomic<bool>
would be enough…
-- EDIT --
Finally, there is a good example in the documentation: std::mutex
-- EDIT #2 --
As pointed out in a comment, my answer is not fully valid for general cases. I do think that the above code would works correctly with a bool
provide that it can only change from true
to false
.
So I have done a search on the web and found those articles: