前提
:以往的mutex如果拿锁子拿不到,就会一直等待。
timed_mutex 和 recursive_timed_mutex则不同,这两个提供了方法,可以不一直等待。
try() 方法--mutex 和 timed_mutex 都有,且说明都一样
bool try_lock(); (C++11 起) 尝试锁定互斥。立即返回。成功获得锁时返回 true ,否则返回 false 。 允许此函数虚假地失败而返回 false ,即使互斥当前未为任何其他线程所锁定。 若已占有 mutex 的线程调用 try_lock ,则行为未定义。 若此操作返回 true ,则同一互斥上的先前 unlock() 操作同步于(定义于 std::memory_order )它。注意若此操作返回 false ,则先前的 lock() 不与之同步。 参数 (无) 返回值 若成功取得锁则为 true ,否则为 false 。
try_lock_for()
template< class Rep, class Period > bool try_lock_for( const std::chrono::duration<Rep,Period>& timeout_duration ); (C++11 起) 尝试锁互斥。阻塞直到经过指定的 timeout_duration 或得到锁,取决于何者先到来。成功获得锁时返回 true , 否则返回 false 。 若 timeout_duration 小于或等于 timeout_duration.zero() ,则函数表现同 try_lock() 。 由于调度或资源争议延迟,此函数可能阻塞长于 timeout_duration 。 标准推荐用 steady_clock 度量时长。若实现用 system_clock 代替,则等待时间亦可能对时钟调整敏感。 同 try_lock() ,允许此函数虚假地失败并返回 false ,即使在 timeout_duration 中某点互斥不为任何线程所锁定。 若此操作返回 true ,则同一互斥上先前的 unlock() 调用同步于(定义于 std::memory_order )它。 若已占有 mutex 的线程调用 try_lock_for ,则行为未定义。
std::mutex cout_mutex; // 控制到 std::cout 的访问 std::timed_mutex mutex; void job(int id) { using Ms = std::chrono::milliseconds; std::ostringstream stream; for (int i = 0; i < 3; ++i) { if (mutex.try_lock_for(Ms(100))) { stream << "success "; std::this_thread::sleep_for(Ms(100)); mutex.unlock(); } else { stream << "failed "; } std::this_thread::sleep_for(Ms(100)); } std::lock_guard<std::mutex> lock(cout_mutex); std::cout << "[" << id << "] " << stream.str() << " "; } int main() { std::vector<std::thread> threads; for (int i = 0; i < 4; ++i) { threads.emplace_back(job, i); } for (auto& i: threads) { i.join(); } }
try_lock_until()
std::timed_mutex::try_lock_until template< class Clock, class Duration > bool try_lock_until( const std::chrono::time_point<Clock,Duration>& timeout_time ); (C++11 起) 尝试所互斥。阻塞直至抵达指定的 timeout_time 或得到锁,取决于何者先到来。成功获得锁时返回 true ,否则返回 false 。 若已经过 timeout_time ,则此函数表现同 try_lock() 。 Clock 必须符合时钟 (Clock) 要求。若 std::chrono::is_clock_v<Clock> 为 false 则程序为非良构。 (C++20 起) 标准推荐使用绑定到 timeout_time 的时钟,该情况下可以计入时钟的调整。从而在调用时刻,阻塞的时长可以,但也可以不,小于或大于 timeout_time - Clock::now() 。这取决于调整的方向以及实现是否尊重它。函数亦可能由于调度或资源纠纷延迟,而阻塞长于到抵达 timeout_time 之后。 同 try_lock() ,允许此函数虚假地失败并返回 false ,即使在 timeout_time 前的某点任何线程都不锁定互斥。 若此操作返回 true ,则同一互斥上先前的 unlock() 调用同步于(定义于 std::memory_order )它。 若已占有 mutex 的线程调用 try_lock_until ,则行为未定义。
#include <thread> #include <iostream> #include <chrono> #include <mutex> std::timed_mutex test_mutex; void f() { auto now=std::chrono::steady_clock::now(); test_mutex.try_lock_until(now + std::chrono::seconds(10)); std::cout << "hello world "; } int main() { std::lock_guard<std::timed_mutex> l(test_mutex); std::thread t(f); t.join(); }