Open In App

Condition Variables in C++ Multithreading

Last Updated : 04 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In C++, the condition variable is a synchronization primitive that is used to notify the other threads in a multithreading environment that the shared resource is free to access. It is defined as the std::condition_variable class inside the <condition_variabel> header file.

Prerequisite: C++ Multithreading, Mutex in C++.

Need for Condition Variable in C++

Condition variable is especially needed in cases where one thread has to wait for another thread execution to continue the work. For example, the producer-consumer relationship, sender-receiver relationship, etc.

In these cases, the condition variable makes the thread wait till it is notified by the other thread. It is used with mutex locks to block access to the shared resource when one thread is working on it.

Syntax of std::condition_variable

The syntax to declare a condition variable is simple:

std::condition_variable variable_name;

After that, we use the associated method for different operations.

Condition Variable Methods

The std::condition_variable methods contain some member methods to provide the basic functionalities. Some of these are:

S. No. Function Description

1

wait() This function tells the current thread to wait till the condition variable is notified.

2

wait_for() This function tells the current thread to wait for some specific time duration. If the condition variable is notified earlier than the time duration, the thread awakes. The time is specified as relative time.

3

wait_until() This function is similar to the wait_for() but here, the time duration is defined as the absolute time.

4

notify_one() This function notifies one of the waiting threads that the shared resource is free to access. The thread selection is random.

5

notify_all()                   This function notifies all of the threads.

Example: Program to Illustrate the Use of Condition Variable

C++




// C++ Program to illustrate the use of Condition Variables
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
  
using namespace std;
  
// mutex to block threads
mutex mtx;
condition_variable cv;
  
// function to avoid spurios wakeup
bool data_ready = false;
  
// producer function working as sender
void producer()
{
    // Simulate data production
    this_thread::sleep_for(chrono::seconds(2));
  
    // lock release
    lock_guard<mutex> lock(mtx);
  
    // variable to avoid spurious wakeup
    data_ready = true;
  
    // logging notification to console
    cout << "Data Produced!" << endl;
  
    // notify consumer when done
    cv.notify_one();
}
  
// consumer that will consume what producer has produced
// working as reciever
void consumer()
{
    // locking
    unique_lock<mutex> lock(mtx);
  
    // waiting
    cv.wait(lock, [] { return data_ready; });
  
    cout << "Data consumed!" << endl;
}
  
// drive code
int main()
{
    thread consumer_thread(consumer);
    thread producer_thread(producer);
  
    consumer_thread.join();
    producer_thread.join();
  
        return 0;
}


Output

Data Produced!
Data consumed!

In this program, the consumer thread uses the condition variable cv to wait until data_ready is set to true while the producer thread sleeps for two seconds to mimic data generation.

Errors Associated with C++ Condition Variable

The condition variable is prone to the following errors:

  1. Spurious Wakeup: Spurious wakeup refers to the condition when the consumer/receiver thread finishes its work before it is notified by the producer/sender. In the above example, we have used the variable data_ready precisely to cope with this error.
  2. Lost Wakeup: Lost wakeup refers to the condition when the sender sends the notification but there is no receiver in the wait for the notification yet.

Advantages of Condition Variable

The following are the major advantages of using condition variables in our C++ program:

  1. The condition variable provide a way to signal the thread of a particular condition.
  2. The sleeping thread in condition variable is different from the waiting threads consuming less resources.

Conclusion

In conclusion, condition variables are an effective tool for assuring safe access to shared data, lowering contention, and establishing effective thread synchronisation in multi-threaded C++ programmes. They are commonly used with the mutex to provide an efficient synchronization technique.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads