On 06/06/2011 12:07 PM, Steven Schveighoffer wrote:
On Mon, 06 Jun 2011 14:09:25 -0400, Ali Çehreli <acehr...@yahoo.com> wrote:

First, the answer may be as simple as "use
core.thread.thread_joinAll". Is that the proper way of waiting for all
threads?

main (the C main, not D main) does this already:

https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L512


But note that "daemonized" threads will not be included:

http://www.digitalmars.com/d/2.0/phobos/core_thread.html#isDaemon

-Steve

Thank you but it doesn't explain the inconsistent behavior. It seems like thread_joinAll() has a different idea at different times. Now I also print the result of isDaemon():

import std.stdio;
import std.concurrency;
import core.thread;

void tell_daemon_state(string name)
{
    writeln(name, " isDaemon: ", Thread.getThis.isDaemon);
}

void foo()
{
    tell_daemon_state("foo");

    foreach (i; 0 .. 5) {
        Thread.sleep(dur!"msecs"(500));
        writeln(i, " foo");
    }
}

void intermediate()
{
    tell_daemon_state("intermediate");

    spawn(&foo);
    writeln("intermediate done");
}

void main()
{
    tell_daemon_state("main");

    spawn(&intermediate);
    writeln("main done");
}

I see that only the main thread is a daemon:

main isDaemon: true
main done
intermediate isDaemon: false
intermediate done
foo isDaemon: false
0 foo
1 foo
2 foo
3 foo
4 foo

That makes sense.

There is a race condition: Just because I added the printing of the isDaemon state, now foo() runs to completion seemingly everytime I start the program. When I remove the printing AND run the program under 'time', I get inconsistent behavior.

The following are two consecutive runs:

$ time ./deneme
main done
intermediate done
0 foo                    <--- foo()'s output is present
1 foo
2 foo
3 foo
4 foo

real    0m2.504s
user    0m0.000s
sys     0m0.000s

$ time ./deneme
main done
intermediate done        <--- foo()'s output is missing

real    0m0.003s
user    0m0.000s
sys     0m0.000s

As if thread_joinAll() misses the fact that there is still the non-daemon foo() thread.

Note that it's not failing to flush stdout either. The program runs shorter in the case where foo()'s output is missing.

Thank you,
Ali

Reply via email to