Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a lock with condition variables

Consider the following simplistic example of condition variables:

bool pause = true;

boost::mutex::scoped_lock lock(m_mutex);
while (!pause) cv.wait(lock);

and

boost::mutex::scoped_lock lock(m_mutex);
pause = false;
cv.notify_one();

Do we essentially need the scoped_lock or any other lock here, if we are running the code on a processor which supports updates on byte-granularity. This essentially means that the assignment of bools are atomic which is typically the case with x86 processors.

Has it got something to do with syncing of the variable in the case when the two threads are running on two different processors and have separate caches?

like image 597
nishantsingh Avatar asked Jul 10 '26 23:07

nishantsingh


1 Answers

Yes you do, and using atomic is not sufficient.

CVs for efficiency can be woken spuriously, and those spurious lookups (or similar issues) can cause a write to be missed.

Imagine a spurious wake up. The recieving thread checks the bool, sees nothing (false), then is preempted. Someone notify all's and sets the bool. The notification is discarded, as the recieving thread is already processing one. The recieving thread now completes, and misses the message.

Now, add a lock in the sender that overlaps some time sequenced after the bool is set and before the cv notification. This communicaton hole no longer exists.

(Even without spurious wakeups, multiple notifications can cause similar problems sometimes.)

You do not have to hold the lock while notifying (and in fact this is a pessimization), but the lock must be held post-write and pre-notify for some period, in general.

like image 99
Yakk - Adam Nevraumont Avatar answered Jul 13 '26 15:07

Yakk - Adam Nevraumont



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!