| Thread overview | ||||||||
|---|---|---|---|---|---|---|---|---|
|
April 14, 2012 Thread join behaviour | ||||
|---|---|---|---|---|
| ||||
Attachments:
| I thought the following would terminate gracefully having printed 0..9
in some (random) order:
#! /usr/bin/env rdmd
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.
--
Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder@ekiga.net 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
| |||
April 14, 2012 Re: Thread join behaviour | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Russel Winder | On 14-04-2012 18:04, Russel Winder wrote: > I thought the following would terminate gracefully having printed 0..9 > in some (random) order: > > #! /usr/bin/env rdmd > > 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... -- - Alex | |||
April 14, 2012 Re: Thread join behaviour | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On 04/14/2012 04:56 PM, Alex Rønne Petersen wrote:
> On 14-04-2012 18:04, Russel Winder wrote:
>> I thought the following would terminate gracefully having printed 0..9
>> in some (random) order:
>>
>> #! /usr/bin/env rdmd
>>
>> 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...
>
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...
-Matt
| |||
April 14, 2012 Re: Thread join behaviour | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Russel Winder | 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:
>
> #! /usr/bin/env rdmd
>
> 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.
>
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.
| |||
April 15, 2012 Re: Thread join behaviour | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matt Soucy Attachments:
| 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(); > 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... 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. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder@ekiga.net 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 | |||
April 15, 2012 Re: Thread join behaviour | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Somedude Attachments:
| On Sat, 2012-04-14 at 23:27 +0200, Somedude wrote: [...] > 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. Thanks for this, a useful alternative realization. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder@ekiga.net 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply