Daily bit(e) of C++ | std::timed_mutex, std::recursive_timed_mutex, std::shared_timed_mutex
Daily bit(e) of C++ #19, The timed mutex variants: std::timed_mutex, std::recursive_timed_mutex, std::shared_timed_mutex
Timed mutex variants (std::timed_mutex
, std::recursive_timed_mutex
and std::shared_timed_mutex
) offer support for timeouts when waiting on a lock. The timeout the be specified as either a time point or a duration.
Adding timeouts to mutexes allows a program to give up waiting on a lock and potentially report an error instead of being stuck in a hard-to-detect state.
#include <thread>
#include <mutex>
#include <chrono>
#include <syncstream>
#include <iostream>
using namespace std::chrono_literals;
std::timed_mutex mux;
// This thread will hold the lock for 2 seconds
auto t = std::jthread([&mux]{
std::unique_lock lock(mux);
std::this_thread::sleep_for(2s);
});
auto runner = [&mux]{
// Try to obtain the lock for 200ms
std::unique_lock lock(mux, 200ms);
if (!lock.owns_lock()) {
std::osyncstream(std::cerr) << "Unable to obtain lock.\n";
return;
}
std::osyncstream(std::cerr) << "Lock was obtained.\n";
};
// Generally, first two attempts will time out
// the other two attempts should succeed.
auto r1 = std::jthread(runner);
std::this_thread::sleep_for(1s);
auto r2 = std::jthread(runner);
std::this_thread::sleep_for(1s);
auto r3 = std::jthread(runner);
std::this_thread::sleep_for(1s);
auto r4 = std::jthread(runner);