我试图使用以下代码对条件变量进行无限等待(只是显示问题的示例):
std::condition_variable cond;
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
cond.wait_for(lock, std::chrono::steady_clock::duration::max());
但是等待立即结束。深入研究
wait_for
的(MS)实现,我发现它实际上使用 wait_until
函数。但在此之前,它会通过调用 chrono::system_clock::now()
来转换时间并添加持续时间。
当然,这会导致整数溢出,因此新时间变为 <= 'now'. Thus
wait_until
立即退出。
所有其他定时等待函数也会发生同样的情况(例如 try_lock_for
类中的 std::timed_mutex
)。
总结以上,我想问一下这是否是定时等待函数实现中的一个bug,如果是的话,我在哪里可以写到它?
此外,由于
wait_until
使用了system_clock
,如果等待期间有时间调整,实际等待时间应该会有所不同(因为system_clock
不是单调的)。因此没有信任等待时间。
cpp参考文档说:
请注意,
必须足够小,以免在添加到rel_time
时溢出。std::chrono::steady_clock::now()
并且:
使用与 timeout_time 相关的时钟,该时钟不需要是单调时钟。如果不连续调整时钟,则无法保证此函数的行为,但现有实现将 timeout_time 从 Clock 转换为
并委托POSIXstd::chrono::system_clock
以便等待遵循对系统时钟的调整,但不遵循用户提供的时钟的调整。在任何情况下,由于调度或资源争用延迟,该函数的等待时间也可能比达到pthread_cond_timedwait
后等待的时间更长。timeout_time
即使使用的时钟是
或其他单调时钟,系统时钟调整也可能会导致虚假唤醒。std::chrono::steady_clock
如果你想要无限超时,你可以这样做(未经测试):
wait_until(lock, std::chrono::sys_time::max());
有点晚了,但对其他人来说也许很有趣:如果你想无休止地等待,就这样做
std::condition_variable cond;
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
cond.wait(lock);
但是,由于虚假唤醒,我还会使用谓词条件,如上面的评论中已经提到的。