Trying to acquire a mutex twice will cause undefined behavior.
In most debug implementations, it will likely result in a crash.
The HelloWorld() function locks a mutex and then calls GoodBye().
What is interesting is that there will be no issue in the normal code path – the problem will only happen when the exception codepath is triggered, in which case we'll get in an undefined state/crash.
#include <iostream> #include <thread> #include <mutex> std::mutex mu; static int counter = 0; void GoodBye() { try { // Some operation. } catch (...) { std::lock_guard<std::mutex> lock(mu); std::cout << "Good Bye" << std::endl; } } void HelloWorld() { std::lock_guard<std::mutex> lock(mu); counter++; GoodBye(); } int main() { std::thread t1(HelloWorld); t1.join(); return 0; }
Structure the code in such a way that it does not try to acquire a previously locked mutex.
A superficial solution might be to just use a std::recursive_mutex — but this is almost always indicative of a bad design.