Codementor Events

Condition Variable: What is the problem with Mutex alone?

Published Apr 05, 2020

Welcome folks,
“If you are waiting for the Right Time, its now.”

So lets start it because this is the right time.
Source file is here.

If you have gone through my last article “Thread: How can I create a thread?”, I recommend to go through this article before continuing here, you know how to synchronize multiple threads to access a shared resource. That program for printing even-odd number is working fine.

But there is a problem.
Lets assume instead of int shared in our last program we have a queue (vector<int> que) which is shared between multiple thread. Lets say one producer thread(t1) is responsible for populating data and pushing into queue. There are other consumer threads(I am considering single thread for simplicity, thread t2) continually reading from this queue and processing on the produced data.

Now for some reason producer thread t1 stopped producing data. Now all consumer threads(in our case t2) will keep checking for the data in queue and acquire lock. At some point when there is no data in queue, consumer threads will continue to check for data in queue.

Now the problem is that there is no data but all consumer threads are checking for data and consuming CPU cycles. If there are 2-3 threads, it will not impact but assume we have a application with 1000s of consumer threads or may be 10k consumer threads. Now this polling will waste significant amount of CPU cycles.

So what is the solution?
As title suggest, Condition Variable.

Condition variables provide yet another way for threads to synchronize. While mutex implement synchronization by controlling thread access to data, condition variables allow threads to synchronize based upon the actual value of data.

Without condition variables, the programmer would need to have threads continually polling (possibly in a critical section), to check if the condition is met. This can be very resource consuming since the thread would be continuously busy in this activity. A condition variable is a way to achieve the same goal without polling.

A condition variable is always used in conjunction with a mutex lock.

Lets try to simulate this mutex problem and solve it using condition variable.

int fun1(){
std::this_thread::sleep_for(std::chrono::seconds(2));
while(count < 100){
cout<<"Fun1: count: "<<count<<endl;
count++;
unique_lock<mutex> lock(mutObj);
que.push_back(count);}}

In fun1() we are populating a queue till count < 100. I don’t want to run this thread infinite. I want you to analyze the output prints.

int fun2(){
unique_lock<mutex> lock1(mutObj);
while((count < 100) || (que.size() > 0)){
cout<<"fun2: que size: "<< que.size()<<endl;
for(autoitr : que){
if(que.size() > 0){
cout<<"Count: "<<itr<<endl;
que.pop_back();}}}}

After running this code, you will observe that while thread t1 is in sleep for 2 seconds but still thread t2 is running and “ fun2:que size: 0 ” is printing and iterating on 'que'. Thread t2 is still consuming CPU cycles. If there are more threads, you can imagine the performance impact.

Now lets uncomment line number 23 in code.

CondVar.notify_all();

Lets also uncomment line 31, 32, 33 .

if((que.size() == 0)){
CondVar.wait(lock1);}

Now while running this code, you will observe that thread t2 is waiting for 2 seconds to notification from thread t1.

What happens here is, thread t2 is waiting for signal from thread t1 after completion of its job.
For more clarity, you can check CPU usages in both cases.

Important std::condition_variable functions:

  • Wait() : It makes the current thread to block until the condition variable get signaled or a spurious wake up happens.
  • notify_one() : If any threads are waiting on same conditional variable object then notify_one unblocks one of the waiting threads.
  • notify_all() : If any threads are waiting on same conditional variable object then notify_all unblocks all of the waiting threads.

So folks this is a brief about condition variable, more importantly why condition variable is required with mutex.

For more intersting information check my other posts or click here.

I you have any query or any suggestions, please contact me

Discover and read more posts from Dheeraj Jha
get started
post commentsBe the first to share your opinion
Dheeraj Jha
4 years ago

For more interesting blogs, check out
https://www.jhadheeraj.com/blog

Show more replies