在“C++并发操作”第387页。
template<typename Lockable, typename Rep, typename Period>
std::cv_status wait_for(
Lockable& lock,
std::chrono::duration<Rep, Period> const& relative_time);
注虚假唤醒意味着调用wait_for()
的线程可能会唤醒,即使没有线程调用notify_one()
或notify_all()
。 因此,建议在可能的情况下优先使用接受谓词的wait_for()
重载。 否则,建议在测试与条件变量关联的谓词的循环中调用wait_for()
。 执行此操作时必须小心,以确保超时仍然有效; WAIT_UNTILE()
在许多情况下可能更合适。 线程被阻塞的时间可能超过指定的持续时间。 在可能的情况下,经过的时间由稳定的时钟确定。
为什么当我们使用wait_for()
时,线程可能会被阻塞超过指定的持续时间?
操作系统通常不会阻止您编写或运行试图使用比系统可用资源更多的资源的程序。 操作系统不会阻止您在磁盘空间不足的情况下运行系统。 它不会阻止您的程序耗尽内存。 它不会阻止您的程序发生故障,因为它们需要比您的ISP提供的更多的网络带宽。 而且,没有任何操作系统(据我所知)会阻止您运行那些在您希望某个线程被唤醒时已经使用了所有可用CPU内核的线程和/或程序。
如果您需要更好的能力来精确控制程序中某些线程何时唤醒并执行操作,那么您可能需要一个实时操作系统。
来自CPPreference:std::condition_variable::wait_for
由于调度或资源争用延迟,此函数可能阻塞时间超过timeout_duration。
当持续时间到期时,线程处于休眠状态,需要重新调度。 内核调度程序通常在计时器上运行,或者在某个其他事件提示时运行,当它启动时需要一些时间,甚至可能没有空闲的内核来调度线程。
当您的线程被调度时,发生的第一件事是wait_for
在将控制权返回给代码之前重新获取锁。 如果另一个线程当前持有该锁,则这本身就是一个阻塞操作。