Thread Synchronization (C++)

std::condition_variable (C++)

Saw this while working on my SLAM for VR Headset project.

The condition_variable is mainly used to notify the threads about the state of the shared data. It is used with the mutex locks to create processes that automatically wait and notify the state of the resource to each other.

AHA: It’s kind of like using Semaphores?

Resources

Include

#include <condition_variable>

Notify One vs. Notify All

  • notify_one() wakes up only one of the waiting threads and unblock them (more efficient in scenarios where waking up a single thread is sufficient because it avoids unnecessarily waking up multiple threads)
  • notify_all() wakes up all threads waiting on the condition variable. This is necessary in situations where multiple threads may be waiting for the same condition and all need to recheck the condition when it changes.

Source

Good to solve the Producer-Consumer Problem.

mutex mtx; 
condition_variable cv; 
bool data_ready = false; 
 
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(); 
} 
 
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; 
}

Why is the mutex needed, isn't the condition variable enough?

No, you need them in conjunction.

Another example

// condition variable and mutex lock 
condition_variable cv; 
mutex m; 
 
// shared resource 
int val = 0; 
 
void add(int num) { 
	lock_guard<mutex> lock(m); 
	val += num; 
	cout << "After addition: " << val << endl; 
	cv.notify_one(); 
} 
 
void sub(int num)  { 
	unique_lock<mutex> ulock(m); 
	cv.wait(ulock, 
			[] { return (val != 0) ? true : false; }); 
	if (val >= num) { 
		val -= num; 
		cout << "After subtraction: " << val << endl; 
	} 
	else { 
		cout << "Cannot Subtract now!" << endl; 
	} 
	cout << "Total number Now: " << val << endl; 
} 
 
// driver code 
int main() 
{ 
	thread t2(sub, 600); 
	thread t1(add, 900); 
	t1.join(); 
	t2.join(); 
	return 0; 
}

notify_one vs. notify_all

https://stackoverflow.com/questions/43759609/stdcondition-variablenotify-all-i-need-an-example