[英]What is the difference between std::condition_variable::wait_for and std::condition_variable::wait_until?
The reference I'm using explains the two in the following way: 我正在使用的参考文献以下列方式解释了这两个:
wait_for
"blocks the current thread until the condition variable is woken up or after the specified timeout duration" wait_for
“阻塞当前线程,直到条件变量被唤醒或在指定的超时持续时间之后”
wait_until
"blocks the current thread until the condition variable is woken up or until specified time point has been reached" wait_until
“阻塞当前线程,直到条件变量被唤醒或达到指定的时间点”
What is the difference? 有什么区别? Will
wait_until
spin so that the thread can continue exactly (more or less) when it is signaled, whereas wait_for
just adds the thread back into scheduling at that point? 将
wait_until
旋转,以便线程可以在发出信号时完全(或多或少)继续,而wait_for
只是将线程添加回调度点?
The difference is in how the wait duration is represented: wait_for
takes a relative time ("wait for up to 10 seconds"), whereas wait_until
takes an absolute time ("wait until 12:00 on October 30, 2012"). 区别在于如何表示等待持续时间:
wait_for
需要相对时间(“等待最多10秒”),而wait_until
需要一个绝对时间(“等到2012年10月30日12:00”)。
Compare the declarations of the time parameters: 比较时间参数的声明:
// wait_for:
const std::chrono::duration<Rep, Period>& rel_time
// wait_until:
const std::chrono::time_point<Clock, Duration>& abs_time
Your question and other answers have all repeated the difference; 你的问题和其他答案都重复了差异; that
wait_for
waits for a specified amount of time and wait_until
waits until a specified point in time, but the implications are not spelled out. wait_for
等待一段指定的时间, wait_until
等到指定的时间点,但没有说明含义。
A time_point
has an associated clock, and that clock is what's used to determine if the appropriate time has come. time_point
具有相关的时钟,该时钟用于确定是否有适当的时间。 That means that clock adjustments are taken into account by the wait_until
function. 这意味着
wait_until
函数会考虑时钟调整。 wait_until(..., system_clock::now() + std::chrono::seconds(10))
could end up waiting an hour and 10 seconds if the clock happens to be adjusted back by an hour before the wait is up. wait_until(..., system_clock::now() + std::chrono::seconds(10))
如果时钟恰好在等待结束前一小时调整回来,可能会等待一小时10秒。
A duration does not have any associated clock and therefore wait_for
chooses its own clock. 持续时间没有任何相关的时钟,因此
wait_for
选择自己的时钟。 The standard specifies that it uses std::steady_clock, which cannot be adjusted and advances at a steady rate relative to real time. 该标准规定它使用std :: steady_clock,它无法调整并以相对于实时的稳定速率前进。 This means that
wait_for
will wait for the specified time regardless of any adjustments made to any clocks. 这意味着无论对任何时钟进行任何调整,
wait_for
都将等待指定的时间。 wait_for(..., std::chrono::seconds(10))
is guaranteed to wait 10 seconds (+ some time for the implementation to work and for scheduling issues). wait_for(..., std::chrono::seconds(10))
保证等待10秒(+实现工作和调度问题的时间)。
There is no difference with regard to spinning vs. sleeping the thread; 关于旋转与睡眠线程没有区别; as
wait_for
is specified to behave as if it called wait_until
with steady_clock::now() + duration
. 指定
wait_for
行为就像使用steady_clock::now() + duration
调用wait_until
steady_clock::now() + duration
。
Here's the part of the standard where this is spelled out: 这是标准的一部分,其中详细说明:
2 Implementations necessarily have some delay in returning from a timeout.
2实现从超时返回必然会有一些延迟。 Any overhead in interrupt response, function return, and scheduling induces a “quality of implementation” delay, expressed as duration D i .
中断响应,函数返回和调度中的任何开销都会引起“实现质量”延迟,表示为持续时间D i 。 Ideally, this delay would be zero.
理想情况下,此延迟将为零。 Further, any contention for processor and memory resources induces a “quality of management” delay, expressed as duration D m .
此外,对处理器和存储器资源的任何争用都会引起“管理质量”延迟,表示为持续时间D m 。 The delay durations may vary from timeout to timeout, but in all cases shorter is better.
延迟持续时间可能因超时而异,但在所有情况下,更短的更好。
3 The member functions whose names end in
_for
take an argument that specifies a duration.3名称以
_for
结尾的成员函数采用指定持续时间的参数。 These functions produce relative timeouts.这些函数产生相对超时。 Implementations should use a steady clock to measure time for these functions.
实现应该使用稳定的时钟来测量这些功能的时间。 Given a duration argument D t , the real-time duration of the timeout is D t + D i + D m .
给定持续时间参数D t ,超时的实时持续时间是D t + D i + D m 。
4 The member functions whose names end in
_until
take an argument that specifies a time point.4名称以
_until
结尾的成员函数采用指定时间点的参数。 These functions produce absolute timeouts.这些函数产生绝对超时。 Implementations should use the clock specified in the time point to measure time for these functions.
实现应使用时间点中指定的时钟来测量这些功能的时间。 Given a clock time point argument C t , the clock time point of the return from timeout should be C t + D i + D m when the clock is not adjusted during the timeout.
给定时钟时间点参数C t ,当超时期间未调整时钟时,从超时返回的时钟时间点应为C t + D i + D m 。 If the clock is adjusted to the time C a during the timeout, the behavior should be as follows:
如果在超时期间将时钟调整到时间C a ,则行为应如下所示:
— if C a > C t , the waiting function should wake as soon as possible, ie C a + D i + D m , since the timeout is already satisfied.- 如果C a > C t ,则等待功能应尽快唤醒,即C a + D i + D m ,因为已经满足超时。 [ Note: This specification may result in the total duration of the wait decreasing when measured against a steady clock.
[ 注意:当针对稳定时钟测量时,此规范可能导致等待的总持续时间减少。 —end note ]
- 尾注 ]
— if C a <= C t , the waiting function should not time out untilClock::now()
returns a time C n >= C t , ie waking at C t + D i + D m .- 如果C a <= C t ,则等待函数不应超时,直到
Clock::now()
返回时间C n > = C t ,即在C t + D i + D m处唤醒。 [ Note: When the clock is adjusted backwards, this specification may result in the total duration of the wait increasing when measured against a steady clock.[ 注意:当向后调整时钟时,此规范可能会导致等待的总持续时间在稳定时钟下测量时增加。 When the clock is adjusted forwards, this specification may result in the total duration of the wait decreasing when measured against a steady clock.
当向前调整时钟时,该规范可能导致在对稳定时钟进行测量时等待的总持续时间减少。 —end note ]
- 尾注 ]
An implementation shall return from such a timeout at any point from the time specified above to the time it would return from a steady-clock relative timeout on the difference between C t and the time point of the call to the_until
function.实现应在从上面指定的时间到从C t和调用
_until
函数的时间点之间的差值的稳定时钟相对超时返回的任何时刻从这样的超时返回。 [ Note: Implementations should decrease the duration of the wait when the clock is adjusted forwards.[ 注意:当时钟向前调整时,实现应该减少等待的持续时间。 —end note ]
- 尾注 ]
wait_for
will wait for a certain amount of time. wait_for
将等待一段时间。 It will for example wait for two seconds. wait_until
will wait until some time is reached. wait_until
将等到一段时间后才会到达。 It will for example wait until 23rd of July 2013 11:22:34 pm is reached on the clock. Here is one important difference in their usage as explained in Anthony Williams's book : 正如Anthony Williams的书中所解释的,这是他们使用中的一个重要区别:
Consider this example where a condition variable is waited with a timeout: 考虑这个示例,其中条件变量等待超时:
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;
}
This is the recommended way to wait for condition variables with a time limit, if you're not passing a predicate to the wait.
如果您没有将谓词传递给等待,那么这是等待具有时间限制的条件变量的推荐方法。 This way, the overall length of the loop is bounded .
这样,循环的总长度是有界的 。 As you saw in section 4.1.1, you need to loop when using condition variables if you don't pass in the predicate, in order to handle spurious wakeups.
正如您在第4.1.1节中看到的那样,如果您没有传入谓词,则需要在使用条件变量时循环,以便处理虚假唤醒。 If you use
wait_for()
in a loop, you might end up waiting almost the full length of time before a spurious wake, and the next time through the wait time starts again.如果你在循环中使用
wait_for()
,你可能会在虚假唤醒之前等待几乎整个时间长度,并且下一次等待时间再次开始。 This may repeat any number of times, making the total wait time unbounded .这可能会重复任何次数,使总等待时间无限制 。
IMO, this is one such scenario where wait_for
can't replace wait_until
so easily, because of its resetting nature. IMO,这是一个这样的场景,其中
wait_for
无法轻易替换wait_until
,因为它的重置性质。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.