Using of core.sync.condition.Condition
Steven Schveighoffer
schveiguy at yahoo.com
Mon Oct 24 07:12:46 PDT 2011
On Fri, 21 Oct 2011 14:32:15 -0400, Alexander <aldem+dmars at 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
More information about the Digitalmars-d
mailing list