www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - synchronized / cond.wait

reply "Stefan Rohe" <Stefan.Rohe funkwerk-itk.com> writes:
Hi all,

could someone explain us this "synchronize" behaviour? We do not understand
it.

Two Threads.
First Thread should wait for a condition. This we do in a
synchronized(mutex) block.
The second Thread broadcasts then a notify. This also in a synchronized
block, synchronizing on the same mutex. This should be impossible!? Does the
condition.wait modify the Mutex object so that it after this has another
address?


import tango.core.Thread;
import tango.core.sync.Condition;
import tango.core.sync.Mutex;
import tango.io.Console;

Object lock;
Mutex mutex;
Condition condition;

void print(char[] msg) {
    synchronized (lock) {
        Cout(msg).newline;
    }
}

void produce() {
    while (true) {
        print("notify");
        synchronized (mutex) {
            print("notify lock");
            condition.notify;
            print("notify unlock");
        }
        Thread.sleep(1.0);
    }
}

void consume() {
    while (true) {
        synchronized (mutex) {
            print("wait lock");
            condition.wait;
            print("wait unlock");
        }
        print("notified");
    }
}

void main() {
    lock = new Object;
    mutex = new Mutex;
    condition = new Condition(mutex);
    (new Thread(&consume)).start;
    (new Thread(&produce)).start;
}

Output:
wait lock
notify
notify lock
notify unlock
wait unlock
notified
...


best regards
  Stefan
Mar 31 2009
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Tue, 31 Mar 2009 15:37:33 +0200, Stefan Rohe wrote:

 could someone explain us this "synchronize" behaviour? We do not understand
 it.
 
 Two Threads.
 First Thread should wait for a condition. This we do in a
 synchronized(mutex) block.
 The second Thread broadcasts then a notify. This also in a synchronized
 block, synchronizing on the same mutex. This should be impossible!? Does the
 condition.wait modify the Mutex object so that it after this has another
 address?
The whole point of a condition variable is to allow other threads to acquire the same mutex while you're waiting. What happens is the mutex associated with the conditional variable is unlocked the same instant you start waiting on that variable. When the other thread notifies you, the cond var attempts to lock the mutex again and therefore waits until the other thread either leaves the critical section or starts waiting itself.
Mar 31 2009
parent Sean Kelly <sean invisibleduck.org> writes:
Sergey Gromov wrote:
 Tue, 31 Mar 2009 15:37:33 +0200, Stefan Rohe wrote:
 
 could someone explain us this "synchronize" behaviour? We do not understand
 it.

 Two Threads.
 First Thread should wait for a condition. This we do in a
 synchronized(mutex) block.
 The second Thread broadcasts then a notify. This also in a synchronized
 block, synchronizing on the same mutex. This should be impossible!? Does the
 condition.wait modify the Mutex object so that it after this has another
 address?
The whole point of a condition variable is to allow other threads to acquire the same mutex while you're waiting. What happens is the mutex associated with the conditional variable is unlocked the same instant you start waiting on that variable. When the other thread notifies you, the cond var attempts to lock the mutex again and therefore waits until the other thread either leaves the critical section or starts waiting itself.
Yeah, the idea behind condition variables is that it's rare you'll want to simply wake another thread. You're generally doing so because some state has changed that you want the thread to operate on. On Windows you have to separate the synchronized test from the wait call, which results in spurious wake-ups since another thread may have operated on the state change before the notified thread wakes up and has a chance to do so itself. There's still a remote possibility that a spurious wake-up may occur so you don't want to assume your data structure has data in it or whatever, but in practice this is very rare. For example: //consume synchronized( mutex ) { while( queue.isEmpty() ) // loop to be sure cond.wait(); auto value = queue.pop(); writefln( value ); } If it helps, Object.wait() and Object.notify() in Java were built on the same model.
Mar 31 2009