[thread.condition.condvar] # 32 Concurrency support library [[thread]](./#thread) ## 32.7 Condition variables [[thread.condition]](thread.condition#condvar) ### 32.7.4 Class condition_variable [thread.condition.condvar] [🔗](#lib:condition_variable) namespace std {class condition_variable {public: condition_variable(); ~condition_variable(); condition_variable(const condition_variable&) = delete; condition_variable& operator=(const condition_variable&) = delete; void notify_one() noexcept; void notify_all() noexcept; void wait(unique_lock& lock); templatevoid wait(unique_lock& lock, Predicate pred); template cv_status wait_until(unique_lock& lock, const chrono::time_point& abs_time); templatebool wait_until(unique_lock& lock, const chrono::time_point& abs_time, Predicate pred); template cv_status wait_for(unique_lock& lock, const chrono::duration& rel_time); templatebool wait_for(unique_lock& lock, const chrono::duration& rel_time, Predicate pred); using native_handle_type = *implementation-defined*; // see [[thread.req.native]](thread.req.native "32.2.3 Native handles") native_handle_type native_handle(); // see [[thread.req.native]](thread.req.native "32.2.3 Native handles")};} [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9618) The class condition_variable is a standard-layout class ([[class.prop]](class.prop "11.2 Properties of classes"))[.](#1.sentence-1) [🔗](#lib:condition_variable,constructor) `condition_variable(); ` [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9627) *Throws*: 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#L9631) *Error conditions*: - [(3.1)](#3.1) resource_unavailable_try_again — if some non-memory resource limitation prevents initialization[.](#3.sentence-1) [🔗](#lib:condition_variable,destructor) `~condition_variable(); ` [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9645) *Preconditions*: There is no thread blocked on *this[.](#4.sentence-1) [*Note [1](#note-1)*: 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) `void notify_one() noexcept; ` [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9666) *Effects*: If any threads are blocked waiting for *this, unblocks one of those threads[.](#5.sentence-1) [🔗](#lib:notify_all,condition_variable) `void notify_all() noexcept; ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9677) *Effects*: Unblocks all threads that are blocked waiting for *this[.](#6.sentence-1) [🔗](#lib:wait,condition_variable) `void wait(unique_lock& lock); ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9688) *Preconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either - [(7.1)](#7.1) no other thread is waiting on this condition_variable object or - [(7.2)](#7.2) lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait,wait_for, or wait_until) threads[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9699) *Effects*: - [(8.1)](#8.1) Atomically calls lock.unlock() and blocks on *this[.](#8.1.sentence-1) - [(8.2)](#8.2) When unblocked, calls lock.lock() (possibly blocking on the lock), then returns[.](#8.2.sentence-1) - [(8.3)](#8.3) The function will unblock when signaled by a call to notify_one() or a call to notify_all(), or spuriously[.](#8.3.sentence-1) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9709) *Postconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread[.](#9.sentence-1) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9714) *Throws*: Nothing[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9718) *Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#11.sentence-1) [*Note [2](#note-2)*: This can happen if the re-locking of the mutex throws an exception[.](#11.sentence-2) — *end note*] [🔗](#lib:wait,condition_variable_) `template void wait(unique_lock& lock, Predicate pred); ` [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9734) *Preconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either - [(12.1)](#12.1) no other thread is waiting on this condition_variable object or - [(12.2)](#12.2) lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait,wait_for, or wait_until) threads[.](#12.sentence-1) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9745) *Effects*: Equivalent to:while (!pred()) wait(lock); [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9753) *Postconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread[.](#14.sentence-1) [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9758) *Throws*: Any exception thrown by pred[.](#15.sentence-1) [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9762) *Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#16.sentence-1) [*Note [3](#note-3)*: This can happen if the re-locking of the mutex throws an exception[.](#16.sentence-2) — *end note*] [🔗](#lib:wait_until,condition_variable) `template cv_status wait_until(unique_lock& lock, const chrono::time_point& abs_time); ` [17](#17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9779) *Preconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either - [(17.1)](#17.1) no other thread is waiting on this condition_variable object or - [(17.2)](#17.2) lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait,wait_for, or wait_until) threads[.](#17.sentence-1) [18](#18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9790) *Effects*: - [(18.1)](#18.1) Atomically calls lock.unlock() and blocks on *this[.](#18.1.sentence-1) - [(18.2)](#18.2) When unblocked, calls lock.lock() (possibly blocking on the lock), then returns[.](#18.2.sentence-1) - [(18.3)](#18.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[.](#18.3.sentence-1) - [(18.4)](#18.4) If the function exits via an exception, lock.lock() is called prior to exiting the function[.](#18.4.sentence-1) [19](#19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9808) *Postconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread[.](#19.sentence-1) [20](#20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9813) *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[.](#20.sentence-1) [21](#21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9819) *Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#21.sentence-1) [22](#22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9824) *Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#22.sentence-1) [*Note [4](#note-4)*: This can happen if the re-locking of the mutex throws an exception[.](#22.sentence-2) — *end note*] [🔗](#lib:wait_for,condition_variable) `template cv_status wait_for(unique_lock& lock, const chrono::duration& rel_time); ` [23](#23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9841) *Preconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either - [(23.1)](#23.1) no other thread is waiting on this condition_variable object or - [(23.2)](#23.2) lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_for, orwait_until) threads[.](#23.sentence-1) [24](#24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9852) *Effects*: Equivalent to:return wait_until(lock, chrono::steady_clock::now() + rel_time); [25](#25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9859) *Postconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread[.](#25.sentence-1) [26](#26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9864) *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[.](#26.sentence-1) [27](#27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9870) *Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#27.sentence-1) [28](#28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9875) *Remarks*: If the function fails to meet the postcondition, terminate is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#28.sentence-1) [*Note [5](#note-5)*: This can happen if the re-locking of the mutex throws an exception[.](#28.sentence-2) — *end note*] [🔗](#lib:wait_until,condition_variable_) `template bool wait_until(unique_lock& lock, const chrono::time_point& abs_time, Predicate pred); ` [29](#29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9893) *Preconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either - [(29.1)](#29.1) no other thread is waiting on this condition_variable object or - [(29.2)](#29.2) lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait,wait_for, or wait_until) threads[.](#29.sentence-1) [30](#30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9904) *Effects*: Equivalent to:while (!pred())if (wait_until(lock, abs_time) == cv_status::timeout)return pred();return true; [31](#31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9914) *Postconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread[.](#31.sentence-1) [32](#32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9919) [*Note [6](#note-6)*: The returned value indicates whether the predicate evaluated totrue regardless of whether the timeout was triggered[.](#32.sentence-1) — *end note*] [33](#33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9925) *Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) or any exception thrown by pred[.](#33.sentence-1) [34](#34) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9930) *Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#34.sentence-1) [*Note [7](#note-7)*: This can happen if the re-locking of the mutex throws an exception[.](#34.sentence-2) — *end note*] [🔗](#lib:wait_for,condition_variable_) `template bool wait_for(unique_lock& lock, const chrono::duration& rel_time, Predicate pred); ` [35](#35) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9948) *Preconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either - [(35.1)](#35.1) no other thread is waiting on this condition_variable object or - [(35.2)](#35.2) lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_for, orwait_until) threads[.](#35.sentence-1) [36](#36) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9962) *Effects*: Equivalent to:return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred)); [37](#37) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9969) [*Note [8](#note-8)*: There is no blocking if pred() is initially true, even if the timeout has already expired[.](#37.sentence-1) — *end note*] [38](#38) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9975) *Postconditions*: lock.owns_lock() is true and lock.mutex() is locked by the calling thread[.](#38.sentence-1) [39](#39) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9980) [*Note [9](#note-9)*: The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered[.](#39.sentence-1) — *end note*] [40](#40) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9986) *Throws*: Timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) or any exception thrown by pred[.](#40.sentence-1) [41](#41) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9991) *Remarks*: If the function fails to meet the postcondition, terminate() is invoked ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#41.sentence-1) [*Note [10](#note-10)*: This can happen if the re-locking of the mutex throws an exception[.](#41.sentence-2) — *end note*]