How to implement Canceleable spawn() from parent
Simen Kjærås
simen.kjaras at gmail.com
Tue Jun 30 14:15:34 UTC 2020
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();
}
}
The above code does the trick.
So, what does it do? __gshared means 'this variable is accessible
to all threads'. static this() runs upon creation of any thread
including the main thread. Since the main thread will run first*,
it gets to store its Tid in mainTid, and every other thread will
see a populated mainTid and leave it alone. In the module
destructor, which runs after main(), we call thread_joinAll() iff
we're the main thread.
Now, why should you not do this? Well first, instead of getting a
tidy crash you get a process that doesn't end. Second, there's
the race conditions described below. Third, there's the principle
of least astonishment. D programmers expect that when main()
returns, the program will exit shortly(ish), while this zombie
could continue running indefinitely.
--
Simen
*I'm pretty sure this is possibly wrong, if a module constructor
spawns a new thread. There's also a possible race condition where
newly spawned modules may conceivably not see a properly
initialized mainTid.
More information about the Digitalmars-d-learn
mailing list