Boost logo

Boost Users :

Subject: Re: [Boost-users] [thread] release lock before cond.var. notified?
From: Brian Budge (brian.budge_at_[hidden])
Date: 2013-09-09 18:55:08

On Mon, Sep 9, 2013 at 3:44 PM, Gavin Lambert <gavinl_at_[hidden]> wrote:
> On 9/09/2013 10:34 p.m., Quoth Thomas M:
>> Now the question: Is there a strong point pro or against releasing
>> controllerLock before the notify_all-signal is sent?
>> E.g. is there preference for the first or second variant as below (see
>> placement of curly brackets!), or even a need for one to ensure
>> correctness?
> The normal problem, IIRC, is that notify_all() will only wake up those
> threads that are actually sleeping on the condition variable already. If you
> release the lock early, then another thread might enter the locked region,
> discover that the condition is false, and be about to sleep on the condition
> variable when the notify is triggered -- it then goes to sleep permanently
> because it missed the wakeup event.

You still have to guarantee that any data that needs to live in the
critical section is covered by the mutex lock. You cannot change or
check the condition outside the mutual exclusion region. That's a bad
race. Note that this is not the same as holding the lock when
notifying the condition variable.

>> // simplified code snippet begin - Variant 2
>> // notify_all is issued when controllerLock has already been released
>> {
>> boost::unique_lock<boost::mutex> controllerLock(someMutex);
>> Continue = true;
>> }
>> someCondVar.notify_all();
>> // simplified code snippet end
> Given that you are updating the condition within the mutex I believe that
> this is safe from the above issue. However it still may not be safe due to
> other factors -- for instance, if the memory containing someCondVar becomes
> eligible for deletion once the condition is true (which happens more often
> than you'd think, particularly when the condition includes some sort of
> termination flag/event) then variant 1 is still safe while variant 2 is not.

See my above comment.

> In terms of efficiency, variant 2 is probably more efficient than variant 1
> on a uniprocessor system, but on a multicore system they're probably about
> the same. (As on uniprocessor there is a chance that the notify could cause
> an immediate preemption, lockout, and switchback with variant 1, while on a
> multicore the notifying thread should be able to continue to release the
> lock.)

My hunch is that you're right that it can be quite bad in the
uniprocessor case, and that it's probably not as bad in the
multiprocessor case.


Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at