public member function
<condition_variable>
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。