[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<mutex>& lock); template<class Predicate>void wait(unique_lock<mutex>& lock, Predicate pred); template<class Clock, class Duration> cv_status wait_until(unique_lock<mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time); template<class Clock, class Duration, class Predicate>bool wait_until(unique_lock<mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time,
 Predicate pred); template<class Rep, class Period> cv_status wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& rel_time); template<class Rep, class Period, class Predicate>bool wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& 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<mutex>& 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<class Predicate>
  void wait(unique_lock<mutex>& 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<class Clock, class Duration>
  cv_status wait_until(unique_lock<mutex>& lock,
                       const chrono::time_point<Clock, Duration>& 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<class Rep, class Period>
  cv_status wait_for(unique_lock<mutex>& lock,
                     const chrono::duration<Rep, Period>& 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<class Clock, class Duration, class Predicate>
  bool wait_until(unique_lock<mutex>& lock,
                  const chrono::time_point<Clock, Duration>& 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<class Rep, class Period, class Predicate>
  bool wait_for(unique_lock<mutex>& lock,
                const chrono::duration<Rep, Period>& 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*]
