Am 09.09.2013 16:44, schrieb Brian Budge:
On Sep 9, 2013 3:34 AM, "Thomas M"
mailto:firespot71@gmail.com> wrote: Hi,
Consider a boolean variable, a mutex and a condition variable:
// simplified code snippet begin bool Continue = false; boost::mutex someMutex; boost::condition_variable someCondVar; // simplified code snippet end
A number of (boost-)threads check if the boolean variable is set to
true in order to continue execution, or otherwise wait for this to happen:
// simplified code snippet begin boost::unique_lockboost::mutex threadLock(someMutex); while (Continue == false) { someCondVar.wait(threadLock); } // simplified code snippet end
and a single controller thread is responsible for setting Continue to
true (see snippets below).
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?
// simplified code snippet begin - Variant 1 // notify_all is issued while controllerLock is still being held { boost::unique_lockboost::mutex controllerLock(someMutex); Continue = true; someCondVar.notify_all(); } // simplified code snippet end
// simplified code snippet begin - Variant 2 // notify_all is issued when controllerLock has already been released { boost::unique_lockboost::mutex controllerLock(someMutex); Continue = true; } someCondVar.notify_all(); // simplified code snippet end
My preference is for variant 2. It might be an uncommon case, but it is possible for a context switch at any time, and that can lead to a case where the other thread is notified and will yry to acquire the lock, but the lock is still held by this thread for unknown amount of time.
But am I correct that both variants are safe, so neither deadlocks nor races may occur under any circumstances (ignore any issues outside of the code snippet above)? Once the notify-signal is issued each waiting thread needs to acquire the lock, and hence they get the lock strictly sequentially. I.e. most of them have to wait anyway while some other thread has the mutex locked. Variant 1 has the advantage of 'bundling' the continuation and notification signal, and it also notifies other threads at the earliest possible point - of course given if it's technically allowed to do it while still locking the mutex, which I think is ok but not 100% sure. Thomas