public member function
<condition_variable>

std::condition_variable_any::wait_until

unconditional (1)
template <class Lock, class Clock, class Duration>  cv_status wait_until (Lock& lck,                        const chrono::time_point<Clock,Duration>& abs_time);
predicate (2)
template <class Lock, class Clock, class Duration, class Predicate>       bool wait_until (Lock& lck,                        const chrono::time_point<Clock,Duration>& abs_time,                        Predicate pred);
Wait until notified or time point
The execution of the current thread (which shall currently lock lck) is blocked either until notified or until abs_time, whichever happens first.

在线程阻塞时,函数会自动调用 lck.unlock(),允许其他已锁定的线程继续执行。

Once notified or once it is abs_time, the function unblocks and calls lck.lock(), leaving lck in the same state as when the function was called. Then the function returns (notice that this last mutex locking may block again the thread before returning).

Generally, the function is notified to wake up by a call in another thread either to member notify_one or to member notify_one. But certain implementations may produce spurious wake-up calls without any of these functions being called. Therefore, users of this function shall ensure their condition for resumption is met.

If pred is specified (2), the function only blocks if pred returns false, and notifications can only unblock the thread when it becomes true (which is especially useful to check against spurious wake-up calls). It behaves as if implemented as
1
2
3
4
while (!pred())
  if ( wait_until(lck,abs_time) == cv_status::timeout)
    return pred();
return true;

参数

lck
当前被该线程锁定的一个可锁定对象
所有对该对象的wait 成员函数的并发调用都必须使用相同的底层互斥锁对象
Lock 应为可锁定类型
abs_time
A point in time at which the thread will stop blocking, allowing the function to return.
time_point 是表示特定绝对时间的对象。
pred
一个可调用对象或函数,它不接受任何参数,并返回一个可以被评估为 bool 的值。
此函数会反复调用 pred,直到其求值为 true

返回值

The unconditional version (1) returns cv_status::timeout if the function returns because abs_time has been reached, or cv_status::no_timeout otherwise.
谓词版本 (2) 返回 pred(),而不管超时是否被触发(尽管它只有在被触发时才能为 false)。

数据竞争

该函数执行三个原子操作:
  • lck 的初始解锁和同时进入等待状态。
  • 解除等待状态。
  • 在返回前锁定 lck
对对象的原子操作按照一个单一的总顺序进行排序,此函数中的三个原子操作以与上述相同的相对顺序发生。

异常安全

如果任何参数的值对此函数无效(例如,如果 lck互斥锁对象未被调用线程锁定),则会导致未定义行为

Otherwise, if an exception is thrown, both the condition_variable_any object and the arguments are in a valid state (basic guarantee).

It may throw system_error in case of failure (transmitting any error condition from the respective call to lock or unlock).

谓词版本 (2) 也可能抛出由 pred 抛出的任何异常。

发生异常时,在退出函数作用域之前,会尝试恢复 lck 的状态(通过调用 lck.lock())。
如果与 abs_time 相关的操作抛出异常,则此函数可能抛出异常(请注意,在 <chrono> 中提供的标准 时钟持续时间 类型上的操作永远不会抛出)。

谓词版本 (2) 也可能抛出由 pred 抛出的异常。

如果函数在某个时刻未能恢复锁定并返回(例如,如果尝试锁定或解锁时抛出异常),则会调用 std::terminate

另见