This program will never exit (it should exit):
import std.parallelism;
void main()
{
taskPool;
taskPool.put(task({ while (true) {} }));
}
This seems to happen because of the following destructor (see https://github.com/dlang/phobos/blob/c74537000c96f92c9f664f0504d9be8b7250d309/std/parallelism.d#L988):
// Kill daemon threads.
shared static ~this()
{
auto allThreads = Thread.getAll();
foreach (thread; allThreads)
{
auto pthread = cast(ParallelismThread) thread;
if (pthread is null) continue;
auto pool = pthread.pool;
if (!pool.isDaemon) continue;
pool.stop();
pthread.join();
}
}
The above does not actually kill a daemon thread (which is not something we should take care of, but the OS), it tries to join it, i.e. wait for it to complete on its own (which defeats the purpose of having a thread be a daemon).
I consider this a major issue, because it blocks me from using it with synchronous file IO (threadpool + synchronous file IO is a common use case under Linux), where an uncompleted synchronous file operation in a daemon thread must not block program termination.
To see the differences, compare the following three programs:
This program will never exit (because we try to join the thread):
import core.thread;
void main()
{
auto t = new Thread({ while (true) {} });
t.start();
t.isDaemon = true;
t.join();
}
This program will exit (as it should, the OS takes care of killing the daemon thread):
import core.thread;
void main()
{
auto t = new Thread({ while (true) {} });
t.start();
t.isDaemon = true;
}
This program will never exit (as the created thread is not a daemon thread and its execution blocks program termination):
import core.thread;
void main()
{
auto t = new Thread({ while (true) {} });
t.start();
}
The destructor quoted above needs to be fixed so that it does not try to join daemon threads.
Comment #1 by mm — 2016-07-27T10:31:34Z
> The destructor quoted above needs to be fixed so that it does not try to join daemon threads.
To expand further on this: Since the destructor's supposed job is to kill daemon threads (which it should not do, the point of daemon threads is that this happens automatically), I would propose to just get rid of the entire destructor.
Comment #2 by robert.schadek — 2024-12-01T16:27:35Z