| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
October 21, 2011 Using of core.sync.condition.Condition | ||||
|---|---|---|---|---|
| ||||
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
| ||||
October 24, 2011 Re: Using of core.sync.condition.Condition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexander | 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
| |||
October 24, 2011 Re: Using of core.sync.condition.Condition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Oct 24, 2011, at 7:12 AM, Steven Schveighoffer wrote: > > 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 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 | |||
October 26, 2011 Re: Using of core.sync.condition.Condition | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply