Finally, we have not dealt with the scenario where a thread that acquired a mutex crashed. In this scenario, any thread that attempts to acquire the same mutex would enter a deadlock state as the thread that crashed never gets a chance to call unlock(). One way to prevent this issue is to use std::timed_mutex.
For example, consider the following code:
#include <mutex>
#include <thread>
#include <iostream>
std::timed_mutex m{};
void foo()
{
using namespace std::chrono;
if (m.try_lock_for(seconds(1))) {
std::cout << "lock acquired ";
}
else {
std::cout << "lock failed ";
}
}
int main(void)
{
std::thread t1{foo};
std::thread t2{foo};
t1.join();
t2.join();
return 0;
}
When this is executed, we get the following:
In the preceding example, we tell C++ that the thread is only allowed to wait for 1 second. If the mutex is already acquired and it is not released after 1 second, the try_lock_for() function will exit and return false, allowing the thread to gracefully exit and handle the error without entering a deadlock.