digitalmars.D.learn - Thread join behaviour
- Russel Winder (66/66) Apr 14 2012 I thought the following would terminate gracefully having printed 0..9
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (10/52) Apr 14 2012 http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.htm...
- Matt Soucy (6/71) Apr 14 2012 If you merge the two foreach loops into one, doing t.start();t.join();
- Russel Winder (16/20) Apr 15 2012 =20
- Somedude (14/63) Apr 14 2012 This works:
- Russel Winder (13/31) Apr 15 2012 Thanks for this, a useful alternative realization.
I thought the following would terminate gracefully having printed 0..9
in some (random) order:
=20
import std.algorithm ;
import std.range ;
import std.stdio ;
import core.thread ;
=20
int main ( immutable string[] args ) {
auto threads =3D map ! ( ( int a ) {
void delegate ( ) f ( ) {
return delegate ( ) { writeln ( a ) ; } ;=20
}
return new Thread ( f ) ;
} ) ( iota ( 10 ) ) ;
foreach ( t ; threads ) { t.start ( ) ; }
foreach ( t ; threads ) { t.join ( ) ; }
return 0 ;
}
However, this does not happen, at least with 2.059 on Linux as per
Debian Unstable. Instead I get:
1
2
4
5
8
3
7
6
9
0
core.thread.ThreadException src/core/thread.d(906): Unable to join =
thread
----------------
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initi=
alizingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83) [0x425edb]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initi=
alizingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2=
.main(int, char**).void runMain()+0x17) [0x429bab]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initi=
alizingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2=
.main(int, char**).void tryExec(scope void delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initi=
alizingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2=
.main(int, char**).void runAll()+0x3d) [0x429bf9]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initi=
alizingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2=
.main(int, char**).void tryExec(scope void delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initi=
alizingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3) [0x4294c3]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f1ed17f=
8ead]
----------------
I think I must be having a dumb moment as my reaction continues to be
WTF.
--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n=
et
41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk
London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 14 2012
On 14-04-2012 18:04, Russel Winder wrote:
I thought the following would terminate gracefully having printed 0..9
in some (random) order:
import std.algorithm ;
import std.range ;
import std.stdio ;
import core.thread ;
int main ( immutable string[] args ) {
auto threads = map ! ( ( int a ) {
void delegate ( ) f ( ) {
return delegate ( ) { writeln ( a ) ; } ;
}
return new Thread ( f ) ;
} ) ( iota ( 10 ) ) ;
foreach ( t ; threads ) { t.start ( ) ; }
foreach ( t ; threads ) { t.join ( ) ; }
return 0 ;
}
However, this does not happen, at least with 2.059 on Linux as per
Debian Unstable. Instead I get:
1
2
4
5
8
3
7
6
9
0
core.thread.ThreadException src/core/thread.d(906): Unable to join
thread
----------------
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AE
B96D0D(_Dmain+0x83) [0x425edb]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void runMain()+0x17)
[0x429bab]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void tryExec(scope
void delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void runAll()+0x3d)
[0x429bf9]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void tryExec(scope
void delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9
EAB96D0D(main+0xd3) [0x4294c3]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)
[0x7f1ed17f8ead]
----------------
I think I must be having a dumb moment as my reaction continues to be
WTF.
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html#ERRORS
We can rule out these:
EDEADLK: Can't happen with your code.
EINVAL (second case): No other thread is trying to join.
ESRCH: Shouldn't happen since druntime registers threads with libpthread.
So, the first case of EINVAL (thread is not a joinable thread) must be
the cause. I have no clue *why* though...
--
- Alex
Apr 14 2012
On 04/14/2012 04:56 PM, Alex Rønne Petersen wrote:On 14-04-2012 18:04, Russel Winder wrote:If you merge the two foreach loops into one, doing t.start();t.join(); it doesn't have this issue. Also, when I run your code repeatedly the number of successful numbers printed changes a lot. I'm assuming that you're trying to join a thread that already exited... -MattI thought the following would terminate gracefully having printed 0..9 in some (random) order: import std.algorithm ; import std.range ; import std.stdio ; import core.thread ; int main ( immutable string[] args ) { auto threads = map ! ( ( int a ) { void delegate ( ) f ( ) { return delegate ( ) { writeln ( a ) ; } ; } return new Thread ( f ) ; } ) ( iota ( 10 ) ) ; foreach ( t ; threads ) { t.start ( ) ; } foreach ( t ; threads ) { t.join ( ) ; } return 0 ; } However, this does not happen, at least with 2.059 on Linux as per Debian Unstable. Instead I get: 1 2 4 5 8 3 7 6 9 0 core.thread.ThreadException src/core/thread.d(906): Unable to join thread ---------------- /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(_Dmain+0x83) [0x425edb] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void runMain()+0x17) [0x429bab] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void tryExec(scope void delegate())+0x23) [0x42952b] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void runAll()+0x3d) [0x429bf9] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(extern (C) int rt.dmain2..main(int, char**).void tryExec(scope void delegate())+0x23) [0x42952b] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AEAB96D0D(main+0xd3) [0x4294c3] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f1ed17f8ead] ---------------- I think I must be having a dumb moment as my reaction continues to be WTF.http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html#ERRORS We can rule out these: EDEADLK: Can't happen with your code. EINVAL (second case): No other thread is trying to join. ESRCH: Shouldn't happen since druntime registers threads with libpthread. So, the first case of EINVAL (thread is not a joinable thread) must be the cause. I have no clue *why* though...
Apr 14 2012
On Sat, 2012-04-14 at 17:10 -0400, Matt Soucy wrote: [...]If you merge the two foreach loops into one, doing t.start();t.join();==20it doesn't have this issue. Also, when I run your code repeatedly the=20 number of successful numbers printed changes a lot. I'm assuming that you're trying to join a thread that already exited...This matches with Artur's comment about laziness/strictness, but doing the above is only useful for experimentation, it cannot be a final solution since it enforces serialization of thread execution. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 15 2012
Le 14/04/2012 18:04, Russel Winder a écrit :
I thought the following would terminate gracefully having printed 0..9
in some (random) order:
import std.algorithm ;
import std.range ;
import std.stdio ;
import core.thread ;
int main ( immutable string[] args ) {
auto threads = map ! ( ( int a ) {
void delegate ( ) f ( ) {
return delegate ( ) { writeln ( a ) ; } ;
}
return new Thread ( f ) ;
} ) ( iota ( 10 ) ) ;
foreach ( t ; threads ) { t.start ( ) ; }
foreach ( t ; threads ) { t.join ( ) ; }
return 0 ;
}
However, this does not happen, at least with 2.059 on Linux as per
Debian Unstable. Instead I get:
1
2
4
5
8
3
7
6
9
0
core.thread.ThreadException src/core/thread.d(906): Unable to join
thread
----------------
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9AE
B96D0D(_Dmain+0x83) [0x425edb]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2.main(int, char**).void runMain()+0x17)
[0x429bab]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void
delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2.main(int, char**).void runAll()+0x3d)
[0x429bf9]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F1
3A9AEAB96D0D(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void
delegate())+0x23) [0x42952b]
/tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/initializingWithAMap.d.9532BBED12C814F25F173A9
EAB96D0D(main+0xd3) [0x4294c3]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)
[0x7f1ed17f8ead]
----------------
I think I must be having a dumb moment as my reaction continues to be
WTF.
This works:
int main ( immutable string[] args ) {
auto threadgroup = new ThreadGroup();
void delegate ( ) f (int a ) {
return delegate ( ) { writeln ( a ) ; } ;
}
for ( int n = 0; n < 10; n++ ) {
threadgroup.create(f(n));
}
threadgroup.joinAll( );
return 0 ;
}
Threads are tracked by the threadgroup, which knows who can be joined.
Apr 14 2012
On Sat, 2012-04-14 at 23:27 +0200, Somedude wrote:
[...]
This works:
=20
int main ( immutable string[] args ) {
=20
auto threadgroup =3D new ThreadGroup();
=20
void delegate ( ) f (int a ) {
return delegate ( ) { writeln ( a ) ; } ;
}
=20
for ( int n =3D 0; n < 10; n++ ) {
threadgroup.create(f(n));
}
threadgroup.joinAll( );
return 0 ;
}
=20
Threads are tracked by the threadgroup, which knows who can be joined.
Thanks for this, a useful alternative realization.
--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n=
et
41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk
London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 15 2012









Russel Winder <russel winder.org.uk> 