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