[thread.condition.condvarany]

# 32 Concurrency support library [[thread]](./#thread)

## 32.7 Condition variables [[thread.condition]](thread.condition#condvarany)

### 32.7.5 Class condition_variable_any [thread.condition.condvarany]

#### [32.7.5.1](#general) General [[thread.condition.condvarany.general]](thread.condition.condvarany.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10004)

In [thread.condition.condvarany],
template arguments for template parameters named Lock shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2 Cpp17BasicLockable requirements"))[.](#general-1.sentence-1)

[*Note [1](#general-note-1)*:

All of the standard
mutex types meet this requirement[.](#general-1.sentence-2)

If a type other than one of the
standard mutex types or a unique_lock wrapper for a standard mutex type
is used with condition_variable_any, any
necessary synchronization is assumed to be in place with respect to the predicate associated
with the condition_variable_any instance[.](#general-1.sentence-3)

â *end note*]

[ð](#lib:condition_variable_any)

namespace std {class condition_variable_any {public: condition_variable_any(); ~condition_variable_any();

 condition_variable_any(const condition_variable_any&) = delete;
 condition_variable_any& operator=(const condition_variable_any&) = delete; void notify_one() noexcept; void notify_all() noexcept; // [[thread.condvarany.wait]](#thread.condvarany.wait "32.7.5.2 Noninterruptible waits"), noninterruptible waitstemplate<class Lock>void wait(Lock& lock); template<class Lock, class Predicate>void wait(Lock& lock, Predicate pred); template<class Lock, class Clock, class Duration> cv_status wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time); template<class Lock, class Clock, class Duration, class Predicate>bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time,
 Predicate pred); template<class Lock, class Rep, class Period> cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time); template<class Lock, class Rep, class Period, class Predicate>bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred); // [[thread.condvarany.intwait]](#thread.condvarany.intwait "32.7.5.3 Interruptible waits"), interruptible waitstemplate<class Lock, class Predicate>bool wait(Lock& lock, stop_token stoken, Predicate pred); template<class Lock, class Clock, class Duration, class Predicate>bool wait_until(Lock& lock, stop_token stoken, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred); template<class Lock, class Rep, class Period, class Predicate>bool wait_for(Lock& lock, stop_token stoken, const chrono::duration<Rep, Period>& rel_time, Predicate pred); };}

[ð](#lib:condition_variable_any,constructor)

`condition_variable_any();
`

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10067)

*Throws*: bad_alloc or system_error when an exception is
required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions"))[.](#general-2.sentence-1)

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10072)

*Error conditions*: 

- [(3.1)](#general-3.1)

  resource_unavailable_try_again â if some non-memory resource
limitation prevents initialization[.](#general-3.1.sentence-1)

- [(3.2)](#general-3.2)

  operation_not_permitted â if the thread does not have the
privilege to perform the operation[.](#general-3.2.sentence-1)

[ð](#lib:condition_variable_any,destructor)

`~condition_variable_any();
`

[4](#general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10089)

*Preconditions*: There is no thread blocked on *this[.](#general-4.sentence-1)

[*Note [2](#general-note-2)*:

That is, all
threads have been notified; they can subsequently block on the lock specified in the
wait[.](#general-4.sentence-2)

This relaxes the usual rules, which would have required all wait calls to happen before
destruction[.](#general-4.sentence-3)

Only the notification to unblock the wait needs to happen before destruction[.](#general-4.sentence-4)

Undefined behavior ensues if a thread waits on *this once the destructor has
been started, especially when the waiting threads are calling the wait functions in a loop or
using the overloads of wait, wait_for, or wait_until that take a predicate[.](#general-4.sentence-5)

â *end note*]

[ð](#lib:notify_one,condition_variable_any)

`void notify_one() noexcept;
`

[5](#general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10110)

*Effects*: If any threads are blocked waiting for *this, unblocks one of those threads[.](#general-5.sentence-1)

[ð](#lib:notify_all,condition_variable_any)

`void notify_all() noexcept;
`

[6](#general-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10121)

*Effects*: Unblocks all threads that are blocked waiting for *this[.](#general-6.sentence-1)

#### [32.7.5.2](#thread.condvarany.wait) Noninterruptible waits [[thread.condvarany.wait]](thread.condvarany.wait)

[ð](#lib:wait,condition_variable_any)

`template<class Lock>
  void wait(Lock& lock);
`

[1](#thread.condvarany.wait-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10135)

*Effects*: 

- [(1.1)](#thread.condvarany.wait-1.1)

  Atomically calls lock.unlock() and blocks on *this[.](#thread.condvarany.wait-1.1.sentence-1)

- [(1.2)](#thread.condvarany.wait-1.2)

  When unblocked, calls lock.lock() (possibly blocking on the lock) and returns[.](#thread.condvarany.wait-1.2.sentence-1)

- [(1.3)](#thread.condvarany.wait-1.3)

  The function will unblock when signaled by a call to notify_one(),
a call to notify_all(), or spuriously[.](#thread.condvarany.wait-1.3.sentence-1)

[2](#thread.condvarany.wait-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10145)

*Postconditions*: lock is locked by the calling thread[.](#thread.condvarany.wait-2.sentence-1)

[3](#thread.condvarany.wait-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10149)

*Throws*: Nothing[.](#thread.condvarany.wait-3.sentence-1)

[4](#thread.condvarany.wait-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10153)

*Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.condvarany.wait-4.sentence-1)

[*Note [1](#thread.condvarany.wait-note-1)*:

This can happen if the re-locking of the mutex throws an exception[.](#thread.condvarany.wait-4.sentence-2)

â *end note*]

[ð](#lib:wait,condition_variable_any_)

`template<class Lock, class Predicate>
  void wait(Lock& lock, Predicate pred);
`

[5](#thread.condvarany.wait-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10169)

*Effects*: Equivalent to:while (!pred()) wait(lock);

[ð](#lib:wait_until,condition_variable_any)

`template<class Lock, class Clock, class Duration>
  cv_status wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time);
`

[6](#thread.condvarany.wait-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10185)

*Effects*: 

- [(6.1)](#thread.condvarany.wait-6.1)

  Atomically calls lock.unlock() and blocks on *this[.](#thread.condvarany.wait-6.1.sentence-1)

- [(6.2)](#thread.condvarany.wait-6.2)

  When unblocked, calls lock.lock() (possibly blocking on the lock) and returns[.](#thread.condvarany.wait-6.2.sentence-1)

- [(6.3)](#thread.condvarany.wait-6.3)

  The function will unblock when signaled by a call to notify_one(), a call to notify_all(),
expiration of the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by abs_time,
or spuriously[.](#thread.condvarany.wait-6.3.sentence-1)

- [(6.4)](#thread.condvarany.wait-6.4)

  If the function exits via an exception, lock.lock() is called prior to exiting the function[.](#thread.condvarany.wait-6.4.sentence-1)

[7](#thread.condvarany.wait-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10204)

*Postconditions*: lock is locked by the calling thread[.](#thread.condvarany.wait-7.sentence-1)

[8](#thread.condvarany.wait-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10208)

*Returns*: cv_status​::​timeout if
the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by abs_time expired,
otherwise cv_status​::​no_timeout[.](#thread.condvarany.wait-8.sentence-1)

[9](#thread.condvarany.wait-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10214)

*Throws*: Timeout-related
exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#thread.condvarany.wait-9.sentence-1)

[10](#thread.condvarany.wait-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10219)

*Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.condvarany.wait-10.sentence-1)

[*Note [2](#thread.condvarany.wait-note-2)*:

This can happen if the re-locking of the mutex throws an exception[.](#thread.condvarany.wait-10.sentence-2)

â *end note*]

[ð](#lib:wait_for,condition_variable_any)

`template<class Lock, class Rep, class Period>
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
`

[11](#thread.condvarany.wait-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10235)

*Effects*: Equivalent to:return wait_until(lock, chrono::steady_clock::now() + rel_time);

[12](#thread.condvarany.wait-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10242)

*Postconditions*: lock is locked by the calling thread[.](#thread.condvarany.wait-12.sentence-1)

[13](#thread.condvarany.wait-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10246)

*Returns*: cv_status​::​timeout if
the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by rel_time expired,
otherwise cv_status​::​no_timeout[.](#thread.condvarany.wait-13.sentence-1)

[14](#thread.condvarany.wait-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10252)

*Throws*: Timeout-related
exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#thread.condvarany.wait-14.sentence-1)

[15](#thread.condvarany.wait-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10257)

*Remarks*: If the function fails to meet the postcondition, terminate is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.condvarany.wait-15.sentence-1)

[*Note [3](#thread.condvarany.wait-note-3)*:

This can happen if the re-locking of the mutex throws an exception[.](#thread.condvarany.wait-15.sentence-2)

â *end note*]

[ð](#lib:wait_until,condition_variable_any_)

`template<class Lock, class Clock, class Duration, class Predicate>
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
`

[16](#thread.condvarany.wait-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10273)

*Effects*: Equivalent to:while (!pred())if (wait_until(lock, abs_time) == cv_status::timeout)return pred();return true;

[17](#thread.condvarany.wait-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10283)

[*Note [4](#thread.condvarany.wait-note-4)*:

There is no blocking if pred() is initially true, or
if the timeout has already expired[.](#thread.condvarany.wait-17.sentence-1)

â *end note*]

[18](#thread.condvarany.wait-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10289)

[*Note [5](#thread.condvarany.wait-note-5)*:

The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered[.](#thread.condvarany.wait-18.sentence-1)

â *end note*]

[ð](#lib:wait_for,condition_variable_any_)

`template<class Lock, class Rep, class Period, class Predicate>
  bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
`

[19](#thread.condvarany.wait-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10303)

*Effects*: Equivalent to:return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));

#### [32.7.5.3](#thread.condvarany.intwait) Interruptible waits [[thread.condvarany.intwait]](thread.condvarany.intwait)

[1](#thread.condvarany.intwait-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10313)

The following wait functions will be notified
when there is a stop request on the passed stop_token[.](#thread.condvarany.intwait-1.sentence-1)

In that case the functions return immediately,
returning false if the predicate evaluates to false[.](#thread.condvarany.intwait-1.sentence-2)

[ð](#thread.condvarany.intwait-itemdecl:1)

`template<class Lock, class Predicate>
  bool wait(Lock& lock, stop_token stoken, Predicate pred);
`

[2](#thread.condvarany.intwait-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10325)

*Effects*: Registers for the duration of this call *this to get notified on a stop request on stoken during this call and then equivalent to:while (!stoken.stop_requested()) {if (pred())return true;
 wait(lock);}return pred();

[3](#thread.condvarany.intwait-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10339)

[*Note [1](#thread.condvarany.intwait-note-1)*:

The returned value indicates whether the predicate evaluated totrue regardless of whether there was a stop request[.](#thread.condvarany.intwait-3.sentence-1)

â *end note*]

[4](#thread.condvarany.intwait-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10345)

*Postconditions*: lock is locked by the calling thread[.](#thread.condvarany.intwait-4.sentence-1)

[5](#thread.condvarany.intwait-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10349)

*Throws*: Any exception thrown by pred[.](#thread.condvarany.intwait-5.sentence-1)

[6](#thread.condvarany.intwait-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10353)

*Remarks*: If the function fails to meet the postcondition,terminate is called ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.condvarany.intwait-6.sentence-1)

[*Note [2](#thread.condvarany.intwait-note-2)*:

This can happen if the re-locking of the mutex throws an exception[.](#thread.condvarany.intwait-6.sentence-2)

â *end note*]

[ð](#thread.condvarany.intwait-itemdecl:2)

`template<class Lock, class Clock, class Duration, class Predicate>
  bool wait_until(Lock& lock, stop_token stoken,
                  const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
`

[7](#thread.condvarany.intwait-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10369)

*Effects*: Registers for the duration of this call *this to get notified on a stop request on stoken during this call and then equivalent to:while (!stoken.stop_requested()) {if (pred())return true; if (wait_until(lock, abs_time) == cv_status::timeout)return pred();}return pred();

[8](#thread.condvarany.intwait-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10384)

[*Note [3](#thread.condvarany.intwait-note-3)*:

There is no blocking if pred() is initially true,stoken.stop_requested() was already true or the timeout has already expired[.](#thread.condvarany.intwait-8.sentence-1)

â *end note*]

[9](#thread.condvarany.intwait-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10391)

[*Note [4](#thread.condvarany.intwait-note-4)*:

The returned value indicates whether the predicate evaluated to true regardless of whether the timeout was triggered or a stop request was made[.](#thread.condvarany.intwait-9.sentence-1)

â *end note*]

[10](#thread.condvarany.intwait-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10397)

*Postconditions*: lock is locked by the calling thread[.](#thread.condvarany.intwait-10.sentence-1)

[11](#thread.condvarany.intwait-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10401)

*Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")),
or any exception thrown by pred[.](#thread.condvarany.intwait-11.sentence-1)

[12](#thread.condvarany.intwait-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10406)

*Remarks*: If the function fails to meet the postcondition,terminate is called ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#thread.condvarany.intwait-12.sentence-1)

[*Note [5](#thread.condvarany.intwait-note-5)*:

This can happen if the re-locking of the mutex throws an exception[.](#thread.condvarany.intwait-12.sentence-2)

â *end note*]

[ð](#thread.condvarany.intwait-itemdecl:3)

`template<class Lock, class Rep, class Period, class Predicate>
  bool wait_for(Lock& lock, stop_token stoken,
                const chrono::duration<Rep, Period>& rel_time, Predicate pred);
`

[13](#thread.condvarany.intwait-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10422)

*Effects*: Equivalent to:return wait_until(lock, std::move(stoken), chrono::steady_clock::now() + rel_time,
 std::move(pred));
