std::condition_variable(3)

NAME
std::condition_variable - std::condition_variable

Synopsis
   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 another thread both
   modifies a shared variable (the condition), and notifies the condition_variable.
   The thread that intends to modify the shared variable has to
    1. acquire a std::mutex (typically via std::lock_guard)
    2. perform the modification while the lock is held
    3. execute notify_one or notify_all on the std::condition_variable (the lock does
       not need to be held for notification)
   Even if the shared variable is atomic, it must be modified under the mutex in order
   to correctly publish the modification to the waiting thread.
   Any thread that intends to wait on std::condition_variable has to
    1. acquire a std::unique_lock<std::mutex>, on the same mutex as used to protect the
       shared variable
    2. either
             1. check the condition, in case it was already updated and notified
             2. execute wait, wait_for, or wait_until. The wait operations atomically
                release the mutex and suspend the execution of the thread.
             3. When the condition variable is notified, a timeout expires, or a
                spurious wakeup occurs, the thread is awakened, and the mutex is
                atomically reacquired. The thread should then check the condition and
                resume waiting if the wake up was spurious.
                        or
             1. use the predicated overload of wait, wait_for, and wait_until, which
                takes care of the three steps above
   std::condition_variable works only with std::unique_lock<std::mutex>; this
   restriction allows for maximal efficiency on some platforms.
   std::condition_variable_any provides a condition variable that works with any
   BasicLockable object, such as std::shared_lock.
   Condition variables permit concurrent invocation of the wait, wait_for, wait_until,
   notify_one and notify_all member functions.
   The class std::condition_variable is a StandardLayoutType. It is not
   CopyConstructible, MoveConstructible, CopyAssignable, or MoveAssignable.

Member types
   Member type Definition
   native_handle_type implementation-defined

Member functions
   constructor constructs the object
                 (public member function)
   destructor destructs the object
                 (public member function)
   operator= not copy-assignable
   [deleted] (public member function)

Notification
   notify_one notifies one waiting thread
                 (public member function)
   notify_all notifies all waiting threads
                 (public member function)

Waiting
   wait 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
   wait_for after the specified timeout duration
                 (public member function)
                 blocks the current thread until the condition variable is woken up or
   wait_until until specified time point has been reached
                 (public member function)

Native handle
   native_handle returns the native handle
                 (public member function)

Example
   condition_variable is used in combination with a std::mutex to facilitate
   inter-thread communication. // Run this code
 #include <iostream>
 #include <string>
 #include <thread>
 #include <mutex>
 #include <condition_variable>
 std::mutex m;
 std::condition_variable cv;
 std::string data;
 bool ready = false;
 bool processed = false;
 void worker_thread()
 {
     // Wait until main() sends data
     std::unique_lock lk(m);
     cv.wait(lk, []{return ready;});
     // after the wait, we own the lock.
     std::cout << "Worker thread is processing data\n";
     data += " after processing";
     // Send data back to main()
     processed = true;
     std::cout << "Worker thread signals data processing completed\n";
     // Manual unlocking is done before notifying, to avoid waking up
     // the waiting thread only to block again (see notify_one for details)
     lk.unlock();
     cv.notify_one();
 }
 int main()
 {
     std::thread worker(worker_thread);
     data = "Example data";
     // send data to the worker thread
     {
         std::lock_guard lk(m);
         ready = true;
         std::cout << "main() signals data ready for processing\n";
     }
     cv.notify_one();
     // wait for the worker
     {
         std::unique_lock lk(m);
         cv.wait(lk, []{return processed;});
     }
     std::cout << "Back in main(), data = " << data << '\n';
     worker.join();
 }

Output:
 main() signals data ready for processing
 Worker thread is processing data
 Worker thread signals data processing completed
 Back in main(), data = Example data after processing

See also
   condition_variable_any provides a condition variable associated with any lock type
   (C++11) (class)
   mutex provides basic mutual exclusion facility
   (C++11) (class)
   lock_guard implements a strictly scope-based mutex ownership wrapper
   (C++11) (class template)
   unique_lock implements movable mutex ownership wrapper
   (C++11) (class template)