C ++ should be notified of a variable change under lock

I found the following example for a condition variable at www.cppreference.com, http://en.cppreference.com/w/cpp/thread/condition_variable . The call to cv.notify_one () is outside the lock. My question is whether the call should be held while holding the lock to ensure that the waiting threads are actually on hold and will receive a notification signal.

#include <iostream> #include <string> #include <thread> #include <mutex> #include <condition_variable> std::mutex m; std::condition_variable cv; std::string data; bool ready = false; bool processed = false; void worker_thread() { // Wait until main() sends data std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{return ready;}); // after the wait, we own the lock. std::cout << "Worker thread is processing data\n"; data += " after processing"; // Send data back to main() processed = true; std::cout << "Worker thread signals data processing completed\n"; // Manual unlocking is done before notifying, to avoid waking up // the waiting thread only to block again (see notify_one for details) lk.unlock(); cv.notify_one(); } int main() { std::thread worker(worker_thread); data = "Example data"; // send data to the worker thread { std::lock_guard<std::mutex> lk(m); ready = true; std::cout << "main() signals data ready for processing\n"; } cv.notify_one(); // wait for the worker { std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{return processed;}); } std::cout << "Back in main(), data = " << data << '\n'; worker.join(); } 

If the notify_one () call moves inside the lock to ensure that pending threads receive a notification signal,

 // send data to the worker thread { std::lock_guard<std::mutex> lk(m); ready = true; cv.notify_one(); std::cout << "main() signals data ready for processing\n"; } 
+5
source share
3 answers

You do not need to notify under lock. However, since notification occurs logically when the actual value changes (otherwise, why do you notify?), And that the change should occur under the lock, this is often done inside the lock.

There would be no practical observable difference.

+7
source

if I understand your question correctly, it is equivalent to "if the notifier thread blocks the mutex, trying to notify some resume in another thread"

no, it is not necessary and even makes some kind of counter-effect.
when condition_variable notified from another thread, it tries to block the mutexes on which it was strewn. blocking this mutex from another thread will block another other thread that is trying to block it, until the blocking shell goes out of scope.

PS
if you remove the lock from a function that sends data to worker threads, ready and processed should at least be atomic. they are currently synchronized by the lock, but when you remove the lock, they are no longer thread safe

+5
source

If you do not expect a condition variable, the notification will be lost. It doesn't matter if you hold locks. The state variable is a synchronization primitive and does not require locking for protection.

You can skip signals with and without blocking. Mutex only protects regular data, such as ready or processed .

-1
source

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


All Articles