std::condition_variable

From cppreference.com
Defined in header <condition_variable>
class condition_variable;
(since C++11)

The condition_variable class is a synchronization primitive that can be used to block a thread, or multiple threads at the same time, until:

  • a notification is received from another thread
  • a timeout expires, or
  • a spurious wakeup occurs

Any thread that intends to wait on std::condition_variable has to acquire a std::unique_lock first. The wait operations atomically release the mutex and suspend the execution of the thread. When the condition variable is notified, the thread is awakened, and the mutex is reacquired.

The class std::condition_variable is a StandardLayoutType. It is not CopyConstructible, MoveConstructible, CopyAssignable, MoveAssignable.

Contents

[edit] Member types

Member type Definition
native_handle_type implementation-defined

[edit] Member functions

constructs the object
(public member function)
destructs the object
(public member function)
operator=
[deleted]
not copy-assignable
(public member function)
Notification
notifies one waiting thread
(public member function)
notifies all waiting threads
(public member function)
Waiting
blocks the current thread until the condition variable is woken up
(public member function)
blocks the current thread until the condition variable is woken up or after the specified timeout duration
(public member function)
blocks the current thread until the condition variable is woken up or until specified time point has been reached
(public member function)
Native handle
returns the native handle
(public member function)

[edit] Example

#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
 
int main()
{
    std::queue<int> produced_nums;
    std::mutex m;
    std::condition_variable cond_var;
    bool done = false;
    bool notified = false;
 
    std::thread producer([&]() {
        for (int i = 0; i < 5; ++i) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::lock_guard<std::mutex> lock(m);
            std::cout << "producing " << i << '\n';
            produced_nums.push(i);
            notified = true;
            cond_var.notify_one();
        }   
 
        std::lock_guard<std::mutex> lock(m);  
        notified = true;
        done = true;
        cond_var.notify_one();
    }); 
 
    std::thread consumer([&]() {
        std::unique_lock<std::mutex> lock(m);
        while (!done) {
            while (!notified) {  // loop to avoid spurious wakeups
                cond_var.wait(lock);
            }   
            while (!produced_nums.empty()) {
                std::cout << "consuming " << produced_nums.front() << '\n';
                produced_nums.pop();
            }   
            notified = false;
        }   
    }); 
 
    producer.join();
    consumer.join();
}

Possible output:

producing 0
consuming 0
producing 1
consuming 1
producing 2
consuming 2
producing 3
consuming 3
producing 4
consuming 4