Daily bit(e) C++. std::timed_mutex, std::recursive_timed_mutex, std::shared_timed_mutex
Добавлено 20 февраля 2026 в 17:50
Daily bit(e) C++ 19. Варианты мьютексов с таймером, поддерживающие крайний срок и тайм-ауты для метода try_lock.

Когда поток пытается получить блокировку мьютекса, он будет блокироваться до тех пор, пока блокировка не будет получена, потенциально бесконечно.
Однако при работе с операциями, имеющими тайм-аут/крайний срок, нет смысла ждать блокировки после истечения крайнего срока.
Стандартная библиотека предлагает варианты мьютексов с таймером (std::timed_mutex, std::recursive_timed_mutex и std::shared_timed_mutex), которые поддерживают тайм-ауты для метода try_lock:
- на определенную продолжительность: try_lock_for()
- на определенный момент времени: try_lock_until()
Эта поддержка также доступна через std::unique_lock и std::shared_lock.
#include <thread>
#include <mutex>
#include <chrono>
#include <print>
int main()
{
using namespace std::chrono_literals;
std::timed_mutex mux;
// этот поток будет удерживать блокировку 2 сек
auto t = std::jthread([&mux]{
std::unique_lock lock(mux);
std::this_thread::sleep_for(2s);
});
auto runner = [&mux]{
// попытаться получить блокировку, но прекратить попытку через 200 мс
std::unique_lock lock(mux, 200ms);
// внутри вызывает:
// для момента времени: mux.try_lock_until()
// для продолжительности: mux.try_lock_for()
if (not lock.owns_lock())
{
std::println("Unable to obtain lock");
return;
}
std::println("Lock was obtained");
};
std::this_thread::sleep_for(100ms);
// Как правило, первые две попытки зааершатся по тайм-ауту,
// а две последующие попытки должны быть успешными.
for (size_t i = 0; i < 4; ++i)
{
auto r = std::jthread(runner);
std::this_thread::sleep_for(1s);
}
}
