std :: condition_variable :: wait_for和std :: condition_variable :: wait_until有什么区别?

时间:2012-10-30 15:25:00

标签: c++ multithreading c++11 condition-variable

reference I'm using以下列方式解释了两者:

  • wait_for"阻止当前线程,直到条件变量被唤醒或在指定的超时时间后#34;

  • wait_until"阻止当前线程,直到条件变量被唤醒或达到指定的时间点为止#34;

有什么区别?将wait_until旋转,以便线程可以在发出信号时完全(或多或少)继续,而wait_for只是将线程添加回调度点?

4 个答案:

答案 0 :(得分:35)

区别在于如何表示等待持续时间:wait_for需要相对时间(“等待最多10秒”),而wait_until需要一段绝对时间(“等到12: 2012年10月30日00“”。

比较时间参数的声明:

// wait_for:
const std::chrono::duration<Rep, Period>& rel_time

// wait_until:
const std::chrono::time_point<Clock, Duration>& abs_time

答案 1 :(得分:25)

你的问题和其他答案都重复了这些差异; wait_for等待指定的时间,wait_until等待指定的时间点,但不会明确含义。

time_point有一个相关的时钟,该时钟用于确定是否有适当的时间。这意味着wait_until功能会考虑时钟调整。如果在等待结束前一小时将时钟调整回来,wait_until(..., system_clock::now() + std::chrono::seconds(10))可能会等待一小时十秒。

持续时间没有任何关联的时钟,因此wait_for选择自己的时钟。该标准规定它使用std :: steady_clock,它无法调整并以相对于实时的稳定速率前进。这意味着wait_for将等待指定的时间,无论对任何时钟进行任何调整。 wait_for(..., std::chrono::seconds(10))保证等待10秒(+实现工作和调度问题的时间)。

关于旋转与睡眠线程没有区别;指定wait_for的行为就像使用wait_until调用steady_clock::now() + duration一样。


以下是标准的部分内容:

[thread.req.timing] 30.2.4 / 2-4

  

2 实施必然会有一些延迟   从超时。中断响应,函数返回的任何开销,   并表示,调度会导致“实施质量”延迟   作为持续时间 D i 。理想情况下,此延迟将为零。   此外,对处理器和存储器资源的任何争用都会导致   “管理质量”延迟,表示为持续时间 D m 。   延迟持续时间可能因超时而异,但在所有情况下都是如此   越短越好。

     

3 名称以_for结尾的成员函数占用   指定持续时间的参数。这些功能产生相对   超时。实现应该使用稳定的时钟来测量时间   这些功能。给定持续时间参数 D t ,   超时的实时持续时间是 D t + D i + D <子>米

     

4 名称以_until结尾的成员函数占用   指定时间点的参数。这些功能产生绝对   超时。实现应该使用时间中指定的时钟   指出测量这些功能的时间。给定一个时钟时间点   参数 C t ,从超时返回的时钟时间点应该是    C t + D i + D m 在超时期间未调整时钟。如果   在超时期间,时钟被调整为 C a 的时间   应如下:
- 如果 C a &gt; C t ,等待功能应该唤醒   尽快,即 C a + D i + D m ,因为超时已经存在   满意。 [注意:此规范可能会导致总持续时间   等于稳定时钟测量的等待时间减少 -end note   ]

- 如果 C a &lt; = C t ,等待功能不应该超时   Clock::now()返回时间 C n &gt; = C t ,即在醒来C t + D i + D m 。 [   注意:当向后调整时钟时,此规范可能会   在测量时导致等待的总持续时间增加   对抗稳定的时钟。当时钟向前调整时,这个   规范可能导致等待的总持续时间减少   当针对稳定时钟进行测量时。 -end note ]

一个实现   应在指定时间内的任何时间点从超时返回   从上面到稳定时钟相对超时返回的时间   关于 C t 与调用时间点之间的区别   _until功能。 [注意:实施应减少向前调整时钟的等待时间。 -end note ]

答案 2 :(得分:5)

  • wait_for会等待一段时间。例如,它将等待两秒钟。
  • wait_until将等到一段时间。例如,它将等到2013年7月23日晚上11:22:34。时间到了。

答案 3 :(得分:1)

正如Anthony Williams的book中所解释的,这是他们使用中的一个重要区别:

考虑这个示例,其中条件变量等待超时:

std::condition_variable cv;
bool done;
std::mutex m;

bool wait_loop()
{
    auto const timeout= std::chrono::steady_clock::now()+
    std::chrono::milliseconds(500);
    std::unique_lock<std::mutex> lk(m);
    while(!done)
    {
       if(cv.wait_until(lk,timeout)==std::cv_status::timeout)
          break;
    }
    return done;
}
  

这是等待条件变量的推荐方法   时间限制,如果你没有将谓词传递给等待。这条路,   循环的总长度有界。正如你在节中看到的那样   4.1.1,如果你没有传入谓词,你需要在使用条件变量时循环,以便处理虚假的唤醒。如果你使用   wait_for()在循环中,您可能最终等待几乎全长   在虚假醒来之前的时间,以及下一次通过等待   时间又开始了。这可能会重复任何次数,使得   总等待时间无界

国际海事组织,这是一种wait_for无法轻易取代wait_until的情况,因为其重置性质。