Can a single condition variable be used for bi-directional synchronization?

Is it possible to use a single condition variable for bi-directional synchronization (i.e., at different points in time, two different conditions are expected in the same condition variable)? I am sure that no more than one thread will wait for the condition variable at any time. The sample code below illustrates what I'm thinking of:

#include <condition_variable> #include <thread> #include <mutex> #include <iostream> std::condition_variable condvar; std::mutex mutex; int i; void even() { while (i < 10000) { std::unique_lock<std::mutex> lock(mutex); if (i % 2 != 0) { condvar.notify_one(); condvar.wait(lock, [&](){ return i % 2 == 0; }); } i++; std::cout << i << std::endl; } condvar.notify_one(); } void odd() { while (i < 10001) { std::unique_lock<std::mutex> lock(mutex); if (i % 2 != 1) { condvar.notify_one(); condvar.wait(lock, [&](){ return i % 2 == 1; }); } i++; std::cout << i << std::endl; } } int main() { i = 0; std::thread a(even); std::thread b(odd); a.join(); b.join(); } 
+4
source share
2 answers

Yes, it is completely safe. However, I would not call notify_one when you really want to notify all threads waiting for conditions, even if you “know” only one thread will wait.

+6
source

Basically, notification of a condition variable really only declares "the condition you are looking for may have occurred."

The only thing that can have bidirectional communication with one condition variable is that the stream can be triggered by a notification when there is no data available for it. The correct use of condition variables is performed in the while loop, so the worst case is that the thread does not see that the data is available, and returns to sleep again. It is absolutely safe, therefore bi-directional communication with one condition variable is possible.

At the same time, there are few advantages for waking up threads unnecessarily, therefore it is usually preferable to have one mutex that protects data (i.e. you must store mutexes to access data) and two different variable conditions indicating different conditions. This will minimize how much once you wake up a thread to find it on which there is no data to work with (called a "false" notification).

+1
source

Source: https://habr.com/ru/post/1478847/


All Articles