[thread.condition.condvar] (original) (raw)

32 Concurrency support library [thread]

32.7 Condition variables [thread.condition]

32.7.4 Class condition_variable [thread.condition.condvar]

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; native_handle_type native_handle(); };}

The class condition_variable is a standard-layout class ([class.prop]).

Error conditions:

Preconditions: There is no thread blocked on *this.

[Note 1:

That is, all threads have been notified; they can subsequently block on the lock specified in the wait.

This relaxes the usual rules, which would have required all wait calls to happen before destruction.

Only the notification to unblock the wait needs to happen before destruction.

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.

— _end note_]

void notify_one() noexcept;

Effects: If any threads are blocked waiting for *this, unblocks one of those threads.

void notify_all() noexcept;

Effects: Unblocks all threads that are blocked waiting for *this.

void wait(unique_lock<mutex>& lock);

Preconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread, and either

Effects:

Postconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread.

Remarks: If the function fails to meet the postcondition, terminate()is invoked ([except.terminate]).

[Note 2:

This can happen if the re-locking of the mutex throws an exception.

— _end note_]

template<class Predicate> void wait(unique_lock<mutex>& lock, Predicate pred);

Preconditions: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either

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

Postconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread.

Throws: Any exception thrown by pred.

Remarks: If the function fails to meet the postcondition, terminate()is invoked ([except.terminate]).

[Note 3:

This can happen if the re-locking of the mutex throws an exception.

— _end note_]

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

Preconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread, and either

Effects:

Postconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread.

Returns: cv_status​::​timeout if the absolute timeout ([thread.req.timing]) specified by abs_time expired, otherwise cv_status​::​no_timeout.

Remarks: If the function fails to meet the postcondition, terminate()is invoked ([except.terminate]).

[Note 4:

This can happen if the re-locking of the mutex throws an exception.

— _end note_]

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

Preconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread, and either

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

Postconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread.

Returns: cv_status​::​timeout if the relative timeout ([thread.req.timing]) specified by rel_time expired, otherwise cv_status​::​no_timeout.

Remarks: If the function fails to meet the postcondition, terminateis invoked ([except.terminate]).

[Note 5:

This can happen if the re-locking of the mutex throws an exception.

— _end note_]

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

Preconditions: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either

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

Postconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread.

[Note 6:

The returned value indicates whether the predicate evaluated totrue regardless of whether the timeout was triggered.

— _end note_]

Remarks: If the function fails to meet the postcondition, terminate()is invoked ([except.terminate]).

[Note 7:

This can happen if the re-locking of the mutex throws an exception.

— _end note_]

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

Preconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread, and either

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

[Note 8:

There is no blocking if pred() is initially true, even if the timeout has already expired.

— _end note_]

Postconditions: lock.owns_lock() is true and lock.mutex()is locked by the calling thread.

[Note 9:

The returned value indicates whether the predicate evaluates to trueregardless of whether the timeout was triggered.

— _end note_]

Remarks: If the function fails to meet the postcondition, terminate()is invoked ([except.terminate]).

[Note 10:

This can happen if the re-locking of the mutex throws an exception.

— _end note_]