[thread.condition.condvarany.general]

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

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

### 32.7.5 Class condition_variable_any [[thread.condition.condvarany]](thread.condition.condvarany#general)

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

[1](#1)

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

In [[thread.condition.condvarany]](thread.condition.condvarany "32.7.5 Class condition_­variable_­any"),
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"))[.](#1.sentence-1)

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

All of the standard
mutex types meet this requirement[.](#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[.](#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](#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"))[.](#2.sentence-1)

[3](#3)

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

*Error conditions*: 

- [(3.1)](#3.1)

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

- [(3.2)](#3.2)

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

[ð](#lib:condition_variable_any,destructor)

`~condition_variable_any();
`

[4](#4)

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

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

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

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

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

Only the notification to unblock the wait needs to happen before destruction[.](#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[.](#4.sentence-5)

â *end note*]

[ð](#lib:notify_one,condition_variable_any)

`void notify_one() noexcept;
`

[5](#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[.](#5.sentence-1)

[ð](#lib:notify_all,condition_variable_any)

`void notify_all() noexcept;
`

[6](#6)

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

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