digitalmars.D - Using of core.sync.condition.Condition
- Alexander (51/51) Oct 21 2011 Hi,
- Steven Schveighoffer (33/85) Oct 24 2011 When waiting on a condition, you must have its associative mutex locked,...
- Sean Kelly (10/14) Oct 24 2011 locked, or Bad Things could happen. You should also have the mutex =
- Alexander (4/5) Oct 26 2011 OK, thanks. For ages I didn't touch pthreads stuff, so I forgot this ...
Hi, I've the code (see below) which produces an exception (SyncException "Unable to wait for condition") unless "synchronized" is used when waiting on condition (Fedora Linux, 32 bit, DMD 2.055). Do I do something wrong? Using "synchronized" when accessing anything that is synchronization object by itself is a little bit counter-intuitive, IMHO. ---snip--- import std.conv; import std.stdio; import core.thread; import core.sync.mutex; import core.sync.condition; __gshared Mutex mutex; __gshared Condition cond; void logs(string text) { synchronized { writeln(text); } } void worker() { logs("Worker started"); while (true) { //synchronized (mutex) { try { cond.wait(); } catch (Exception ex) { logs("Oops: %s" ~ to!string(ex)); return; } } logs("Got notify"); } } void main() { mutex = new Mutex(); cond = new Condition(mutex); (new Thread(&worker)).start(); (new Thread(&worker)).start(); (new Thread(&worker)).start(); (new Thread(&worker)).start(); Thread.sleep(dur!("msecs")(250)); logs("Sending notify"); cond.notifyAll(); thread_joinAll(); } ---snip--- -- /Alexander
Oct 21 2011
On Fri, 21 Oct 2011 14:32:15 -0400, Alexander <aldem+dmars nk7.net> wrote:Hi, I've the code (see below) which produces an exception (SyncException "Unable to wait for condition") unless "synchronized" is used when waiting on condition (Fedora Linux, 32 bit, DMD 2.055). Do I do something wrong? Using "synchronized" when accessing anything that is synchronization object by itself is a little bit counter-intuitive, IMHO. ---snip--- import std.conv; import std.stdio; import core.thread; import core.sync.mutex; import core.sync.condition; __gshared Mutex mutex; __gshared Condition cond; void logs(string text) { synchronized { writeln(text); } } void worker() { logs("Worker started"); while (true) { //synchronized (mutex) { try { cond.wait(); } catch (Exception ex) { logs("Oops: %s" ~ to!string(ex)); return; } } logs("Got notify"); } } void main() { mutex = new Mutex(); cond = new Condition(mutex); (new Thread(&worker)).start(); (new Thread(&worker)).start(); (new Thread(&worker)).start(); (new Thread(&worker)).start(); Thread.sleep(dur!("msecs")(250)); logs("Sending notify"); cond.notifyAll(); thread_joinAll(); } ---snip---When waiting on a condition, you must have its associative mutex locked, or Bad Things could happen. You should also have the mutex locked when signaling the condition, but I don't think that's an absolute requirement. The typical producer-consumer process works like this: __gshared bool data; void thread1() { while(1) { synchronized(mutex) { if(!data) { data = true; // produce! condition.notify(); } } } } void thread2() { synchronized(mutex) { while(!data) condition.wait(); data = false; // consume! } } The key here is, waiting on a condition atomically unlocks the mutex. If waiting on a condition was allowed without locking the mutex, potentially thread2 could miss thread1's signal, and you encounter a deadlock! -Steve
Oct 24 2011
On Oct 24, 2011, at 7:12 AM, Steven Schveighoffer wrote:=20 When waiting on a condition, you must have its associative mutex =locked, or Bad Things could happen. You should also have the mutex = locked when signaling the condition, but I don't think that's an = absolute requirement.=20 The key here is, waiting on a condition atomically unlocks the mutex. =If waiting on a condition was allowed without locking the mutex, = potentially thread2 could miss thread1's signal, and you encounter a = deadlock! Bartosz just posted a tutorial on Mutexes and Conditions. How timely: = http://www.corensic.com/Learn/Resources/ConcurrencyTutorialPartSeven.aspx=
Oct 24 2011
On 24.10.2011 16:12, Steven Schveighoffer wrote:The key here is, waiting on a condition atomically unlocks the mutex. If waiting on a condition was allowed without locking the mutex, potentially thread2 could miss thread1's signal, and you encounter a deadlock!OK, thanks. For ages I didn't touch pthreads stuff, so I forgot this semantics completely :) -- /Alexander
Oct 26 2011