<condition_variable>

[added with C++11]


condition_variable · condition_variable_any · cv_status


namespace std {
enum class cv_status;
class condition_variable;
class condition_variable_any;
}   // namespace std

condition_variable


condition_variable · ~condition_variable · notify_all · notify_one · native_handle · native_handle_type · wait · wait_for · wait_until


Include the standard header <condition_variable> to define the classes condition_variable and condition_variable_any to create objects that can wait for a condition to become true.

Code that waits for a condition variable must also use a mutex; before calling any of the functions that wait for the condition variable the calling thread must lock the mutex, and when the called function returns the mutex will be locked. During the time that the thread is blocked waiting for the condition to become true the mutex is not locked. When more than one thread is waiting for the same condition variable, all of the waiting threads must use the same mutex object. If they don't, the result is unpredictable.

Objects of type condition_variable_any can be used with a mutex of any type that meets the requirements for a mutex type, except that the type does not have to provide the member function try_lock. Objects of type condition_variable can only be used with a mutex of type unique_lock<mutex>. Objects of this type can be faster than objects of type condition_variable_any<unique_lock<mutex>>.

To wait for an event, first lock the mutex, then call one of the wait member functions on the condition variable. The wait call will block until another thread signals the condition variable.

Spurious wakeups occur when threads waiting for condition variables become unblocked without appropriate notifications. Code that waits for a condition to become true should explicitly check that condition when returning from a wait function to recognize such spurious wakeups. This is usually done with a loop:

while (condition is false)
    wait for condition variable;

The classes condition_variable_any and condition_variable have three member functions to wait for a condition:

Each of these functions has two overloaded versions. One simply waits; it can wake up spuriously. The other takes an additional template argument that defines a predicate; it won't wake up until the predicate is true.

The classes have two member functions to notify a condition variable that its condition is true:

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 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);

    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);

    bool wait_until(
        unique_lock<mutex>& lock,
        const xtime *Abs_time);
    template<class Predicate>
        bool wait_until(
            unique_lock<mutex>& lock,
            const xtime *Abs_time,
            Predicate pred);

    typedef see below native_handle_type;
    native_handle_type native_handle();
    };

Use the class condition_variable to wait for an event when you have a mutex of type unique_lock<mutex>.

condition_variable::condition_variable

condition_variable();

The constructor constructs an object of type condition_variable. If the object cannot be constructed because there is not enough memory available, the constructor throws an object of type system_error with an error code of not_enough_memory. If the object cannot be constructed because some other resource is not available, the constructor throws an object of type system_error with an error code of resource_unavailable_try_again.

condition_variable::~condition_variable

~condition_variable();

The destructor cleans up any resources used by the object.

condition_variable::notify_all

void notify_all() noexcept;

The member function unblocks all threads that are waiting for this object.

condition_variable::notify_one

void notify_one() noexcept;

The member function unblocks one of the threads that is waiting for this object.

condition_variable::native_handle

native_handle_type native_handle();

The member function returns an object of type native_handle_type that can be used in implementation-specific ways.

condition_variable::native_handle_type

typedef h-type native_handle_type;

The typedef is a synonym for an implementation-specific type that can be used in implementation-specific ways.

In this implementation, it is a synonym for cnd_t and can be used as an argument to any of the cnd_XXX functions other than cnd_create and cnd_destroy.

condition_variable::wait

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

The first member function blocks until the condition_variable object is signaled by a call to notify_one or notify_all, but it can wake up spuriously.

The second member function effectively executes the following code:

while (!pred())
    wait(lock);

condition_variable::wait_for

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);

The first member function blocks until the condition_variable object is signaled by a call to notify_one or notify_all or until the time interval Rel_time has elapsed, but it can wake up spuriously. It returns cv_status::timeout if the wait terminated because the specified time elapsed, otherwise cv_status::no_timeout.

The second member function effectively executes the following code:

while (!pred())
    if (wait_for(lock, Rel_time) == cv_status::timeout)
        return pred();
return true;

condition_variable::wait_until

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);

bool wait_until(
    unique_lock<mutex>& lock,
    const xtime *Abs_time);
template<class Predicate>
    bool wait_until(
        unique_lock<mutex>& lock,
        const xtime *Abs_time,
        Predicate pred);

The first member function blocks until the condition_variable object is signaled by a call to notify_one or notify_all or until the time Abs_time, but it can wake up spuriously. It returns cv_status::timeout if the wait terminated because the specified time elapsed, otherwise cv_status::no_timeout. If lock has not been locked by the calling thread, the function throws an object of type system_error with an error code of operation_not_permitted. Otherwise, it calls lock.unlock() before blocking and calls lock.lock() after unblocking.

The second member function effectively executes the following code:

while (!pred())
    if (wait_until(lock, Abs_time) == cv_status::timeout)
        return pred();
return true;

In this implementation, there are two additional overloads of the member function wait_until. They replace the second argument with an argument of type xtime* which designates the maximum time to wait for a signal. In all other respects they act the same as the other two overloads.

condition_variable_any


condition_variable_any · ~condition_variable_any · notify_all · notify_one · native_handle · native_handle_type · wait · wait_for · wait_until


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;

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

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

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

    template<class Lock>
        void wait_until(
            Lock lock,
            const xtime *Abs_time);
    template<class Lock, class Predicate>
        void wait_until(
            Lock lock,
            const xtime *Abs_time,
            Predicate pred);

    typedef see below native_handle_type;
    native_handle_type native_handle();
    };

Use the class condition_variable_any to wait for an event with any mutex type.

condition_variable_any::condition_variable_any

condition_variable_any();

The constructor constructs an object of type condition_variable_any.

condition_variable_any::~condition_variable_any

~condition_variable_any();

The destructor cleans up any resources used by the object.

condition_variable_any::notify_all

void notify_all() noexcept;

The member function unblocks all threads that are waiting for this object.

condition_variable_any::notify_one

void notify_one() noexcept;

The member function unblocks one of the threads that is waiting for this object.

condition_variable_any::native_handle

native_handle_type native_handle();

The member function returns an object of type native_handle_type that can be used in implementation-specific ways.

condition_variable_any::native_handle_type

typedef see below native_handle_type;

The typedef is a synonym for an implementation-specific type that can be used in implementation-specific ways.

In this implementation, the type is not defined and the member function condition_variable_any::native_handle is not provided.

condition_variable_any::wait

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

The first member function blocks until the condition_variable object is signaled by a call to notify_one or notify_all, but it can wake up spuriously.

The second member function effectively executes the following code:

while (!pred())
    wait(lock);

condition_variable_any::wait_for

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

The first member function blocks until the condition_variable_any object is signaled by a call to notify_one or notify_all or until the time interval Rel_time has elapsed, but it can wake up spuriously. It returns false if the wait terminated because the specified time elapsed, otherwise true.

The second member function effectively executes the following code:

while (!pred())
    if (!wait_for(lock, Rel_time))
        return pred();
return true;

condition_variable_any::wait_until

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

template<class Lock>
    void wait_until(
        Lock lock,
        const xtime *Abs_time);
template<class Lock, class Predicate>
    void wait_until(
        Lock lock,
        const xtime *Abs_time,
        Predicate pred);

The first member function blocks until the condition_variable_any object is signaled by a call to notify_one or notify_all or until the time Abs_time, but it can wake up spuriously. It returns false if the wait terminated because the specified time elapsed, otherwise true.

The second member function effectively executes the following code:

while (!pred())
    if !(wait_until(lock, Abs_time))
        return pred();
return true;

In this implementation, there are two additional overloads of the member function wait_until. They replace the second argument with an argument of type xtime* which designates the maximum time to wait for a signal. In all other respects they act the same as the other two overloads.

cv_status

enum class cv_status {
    no_timeout,
    timeout
    };

The scoped enumeration supplies symbolic names for the return values of some member functions of template class condition_variable.


See also the Table of Contents and the Index.

Copyright © 1992-2013 by P.J. Plauger. All rights reserved.