How to implement Canceleable spawn() from parent

Steven Schveighoffer schveiguy at gmail.com
Tue Jun 30 14:43:40 UTC 2020


On 6/30/20 10:15 AM, Simen Kjærås wrote:
> On Tuesday, 30 June 2020 at 13:44:38 UTC, aberba wrote:
>> On Tuesday, 30 June 2020 at 12:48:32 UTC, Simen Kjærås wrote:
>>> On Tuesday, 30 June 2020 at 08:15:54 UTC, aberba wrote:
>>>> On Tuesday, 30 June 2020 at 00:33:41 UTC, Ali Çehreli wrote:
>>>>> On 6/29/20 4:34 PM, aberba wrote:
>>>>>
>>>>> > So with this, without the Thread.sleep() to block main from
>>>>> exiting, the
>>>>> > spawned thread  will terminate immediately.
>>>>>
>>>>> You can call core.thread.thread_joinAll at the end of main.
>>>> So I tried that initially but my (){ writeln(...) } wasn't printing 
>>>> anything in console. Could that be related to stdout buffering? The 
>>>> program kept running though.
>>>
>>
>>>
>>> So I guess the error is elsewhere, but I'm not sure where and how.
>>
>> Yeah, you're right. I changed receiveTimeout() to receive() to try 
>> something and forgot to change it back.
>>
>> Jeez, I hate myself.
>>
>> Thanks.
>>
>>
>> So how can I now hide the core.thread.thread_joinAll so the library 
>> user doesn't have to type it themselves in main() ? I don't see how 
>> that can be done.
> 
> __gshared Tid mainTid;
> static this() {
>      if (mainTid.tupleof[0] is null) {
>          mainTid = thisTid;
>      }
> }
> static ~this() {
>      if (thisTid == mainTid) {
>          thread_joinAll();
>      }
> }
> 

First, you can just use shared static dtor, as this runs once at the end 
of the program. At the very least, you can run the setting of mainTid in 
a shared constructor to avoid the race conditions (also no need to check 
if its set already).

Second, I realized, thread_joinAll is already being done by the runtime:

https://github.com/dlang/druntime/blob/67618bd2dc8905ad5dee95f3329109aebd839b74/src/rt/dmain2.d#L226

So the question really becomes -- why is it necessary to call 
thread_joinAll in main?

It's because the main thread's TLS static destructor is closing the 
owner mailbox, which is sending a message to all the threads that the 
owner is terminated, causing your threads to exit immediately.

See here: 
https://github.com/dlang/phobos/blob/268b56be494cc4f76da54a66a6960fa7e527c4ed/std/concurrency.d#L223

Honestly though, I think this is the correct behavior -- if you exit 
main, you are expecting the program to not hang indefinitely.

-Steve


More information about the Digitalmars-d-learn mailing list