Search code examples
c++multithreadingc++11concurrencyatomic

Condition variables vs atomic types for synchronization


Suppose I have producer and consumer threads synchronized using a condition variable.

// Approach 1 - Using condition variable
mutex mmutex;
condition_variable mcond;
queue<string> mqueue;

void producer(){
    while (true) {
        unique_lock<mutex> lck(mmutex);
        mqueue.push_back("Hello Hi");
        mcond.notify_one();
    }
}

void consumer{
    while (true){
        unique_lock<mutex> lck(mmutex); // locks mmutex
        mcond.wait(); // releases mmutex;
        string s = mqueue.front(); // locks mmutex again
        mqueue.pop();
        mmutex.unlock();
    }
}

How does the above code compare for synchronization using simple atomic types, as follows -

// Approach 2 - using atomics
atomic_bool condition = false;
condition_variable mcond;
queue<string> mqueue;

void producer(){
    unique_lock<mutex> lck(mmutex);
    mqueue.push_back("Hello Hi");
    condition = true;
}

void consumer{
    while (1) {
        if (condition == true) {
            condition = false;
            unique_lock<mutex> lck(mmutex);
            mqueue.front();
            mqueue.pop();
            lck.unlock();
        }
    }
}

Since, condition variables exist, I assume they are the preferred means of achieving synchronization in cases like these. If indeed so, why are condition variables a better alternative to the simple atomic_bool (or atomic_int if you need more then two states) based synchronization? If not, then what is the best way to achieve synchronization in this case?


Solution

  • The difference is that a condition variable doesn't consume CPU cycles while another thread is waiting for it. If you use an atomic variable for synchronization you have to keep checking its value in a loop.