std::condit...::wait_until(3)
โจ std::condition_variable_any::wait_until โจ
bestie, you're in the C++ Standard Library docs, and this page is all about std::condition_variable_any::wait_until โ the "wait until a specific time point" flavor of waiting. it's giving patient queen energy ๐
๐ธ SYNOPSIS ๐ธ
template< class Lock, class Clock, class Duration >
std::cv_status
wait_until( Lock& lock, (1) (since C++11)
const std::chrono::time_point<Clock, Duration>& abs_time );
template< class Lock, class Clock, class Duration, class Predicate >
bool wait_until( Lock& lock, (2) (since C++11)
const std::chrono::time_point<Clock, Duration>& abs_time,
Predicate pred );
template< class Lock, class Clock, class Duration, class Predicate >
bool wait_until( Lock& lock, std::stop_token stoken, (3) (since C++20)
const std::chrono::time_point<Clock, Duration>& abs_time,
Predicate pred );
okay so here's the whole vibe: wait_until makes the current thread block until one of these three things happens โ the condition variable gets notified, the given duration has been elapsed, or a spurious wakeup occurs ๐ด and yeah, pred can be optionally provided to detect spurious wakeup. iykyk ๐ซถ
1) Atomically calls lock.unlock() and blocks on *this. the thread will be unblocked when notify_all() or notify_one() is executed, or abs_time is reached. it may also be unblocked spuriously ๐ญ when unblocked, it calls lock.lock() (possibly blocking on the lock), then returns.
2, 3) waiting for a specific condition to become true โ this is the version you use to ignore spurious awakenings โจ
2) equivalent to:
while (!pred())
if (wait_until(lock, abs_time) == std::cv_status::timeout)
return pred();
return true;
3) registers *this for the duration of this call, to be notified if a stop request is made on stoken's associated stop-state; it is then equivalent to:
while (!stoken.stop_requested())
{
if (pred())
return true;
if (wait_until(lock, abs_time) == std::cv_status::timeout)
return pred();
}
return pred();
โ ๏ธ right afterwait_untilreturns,lockis locked by the calling thread. if this postcondition cannot be satisfied^[1], it callsstd::terminate๐ ^[1] this can happen if the re-locking of the mutex throws an exception.
๐ PARAMETERS ๐
lockโ an lock which must be locked by the calling thread ๐stokenโ a stop token to register interruption for ๐abs_timeโ the time point where waiting expires โฐpredโ the predicate to check whether the waiting can be completed โ
๐ฆ TYPE REQUIREMENTS ๐ฆ
Lockmust meet the requirements ofBasicLockable. ๐งPredicatemust meet the requirements ofFunctionObject. ๐ง
โญ RETURN VALUE โญ
1) std::cv_status::timeout if abs_time has been reached, otherwise std::cv_status::no_timeout. โณ
2, 3) the latest result of pred() before returning to the caller. ๐
๐ EXCEPTIONS ๐
1) timeout-related exceptions.
2, 3) timeout-related exceptions, and any exception thrown by pred.
๐ NOTES ๐
the standard recommends that the clock tied to abs_time be used to measure time; that clock is not required to be a monotonic clock. there are no guarantees regarding the behavior of this function if the clock is adjusted discontinuously, but the existing implementations convert abs_time from Clock to std::chrono::system_clock and delegate to POSIX pthread_cond_timedwait so that the wait honors adjustments to the system clock, but not to the user-provided Clock. in any case, the function also may wait for longer than until after abs_time has been reached due to scheduling or resource contention delays ๐ฎโ๐จ
even if the clock in use is std::chrono::steady_clock or another monotonic clock, a system clock adjustment may induce a spurious wakeup ๐
the effects of notify_one()/notify_all() and each of the three atomic parts of wait()/wait_for()/wait_until() (unlock+wait, wakeup, and lock) take place in a single total order that can be viewed as modification order of an atomic variable: the order is specific to this individual condition variable. this makes it impossible for notify_one() to, for example, be delayed and unblock a thread that started waiting just after the call to notify_one() was made. periodt. ๐
๐ EXAMPLE ๐
// Run this code
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
std::condition_variable_any cv;
std::mutex cv_m; // This mutex is used for three purposes:
// 1) to synchronize accesses to i
// 2) to synchronize accesses to std::cerr
// 3) for the condition variable cv
int i = 0;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cerr << "Waiting... \n";
cv.wait(lk, []{ return i == 1; });
std::cerr << "...finished waiting. i == 1\n";
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lk(cv_m);
std::cerr << "Notifying...\n";
}
cv.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lk(cv_m);
i = 1;
std::cerr << "Notifying again...\n";
}
cv.notify_all();
}
int main()
{
std::thread t1(waits), t2(waits), t3(waits), t4(signals);
t1.join();
t2.join();
t3.join();
t4.join();
}
๐ Possible output:
Waiting...
Waiting...
Waiting...
Notifying...
Notifying again...
...finished waiting. i == 1
...finished waiting. i == 1
...finished waiting. i == 1
๐ฅ DEFECT REPORTS ๐ฅ
the following behavior-changing defect reports were applied retroactively to previously published C++ standards. not me being obsessed with retroactive fixes ๐ญ
LWG 2093โ applied to C++11 โ behavior as published: timeout-related exceptions were missing in the specification โ correct behavior: mentions these exceptions โจLWG 2135โ applied to C++11 โ behavior as published: the behavior was unclear iflock.lock()throws an exception โ correct behavior: callsstd::terminatein this case ๐
๐ง SEE ALSO ๐ง
waitโ blocks the current thread until the condition variable is awakened (public member function) ๐คwait_untilโ blocks the current thread until the condition variable is awakened or until specified time point has been reached (public member function) โฐ
๐ HIDDEN CATEGORY ๐
Pages with unreviewed LWG DR marker
and that's the page, bestie โ sign-off time ๐ซถ this little gem comes to you from http://cppreference.com, version 2024.06.10 ๐ slay, go wait on something responsibly ๐ โจ๐ฆ
๐ฆ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 ยท MIT
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms