Bug 19487 – Thread never detaches after spawn

Status
NEW
Severity
normal
Priority
P3
Component
druntime
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2018-12-14T21:20:34Z
Last change time
2024-12-07T13:38:58Z
Assigned to
No Owner
Creator
Nikolay (unDEFER) Krivchenkov
Moved to GitHub: dmd#17174 →

Comments

Comment #0 by undefer — 2018-12-14T21:20:34Z
Program to test: #!/usr/bin/rdmd import std.stdio; import std.concurrency; import core.thread; import core.memory; void thread() { writefln("Thread %s started", thisTid); Thread.sleep(10.seconds); writefln("Thread %s finished", thisTid); } void main() { for (int i=0; i<1000; i++) { spawn(&thread); } Thread.sleep(13.seconds); writefln("Collect"); GC.collect(); Thread.sleep(10.seconds); } Run as ./threads.d In other console do: $ ps -e | grep threads $ cat /proc/[PID]/maps | wc -l It shows count of maps like 2479. After "Collect" must be something like 243. But it doesn't happen, because in the class Thread: ~this() nothrow @nogc { bool no_context = m_addr == m_addr.init; bool not_registered = !next && !prev && (sm_tbeg !is this); if (no_context || not_registered) { return; } And after finishing of the thread it is always not_registered. Before finishing the thread the dtor can't be run, because it is registered.
Comment #1 by dfj1esp02 — 2018-12-17T11:59:25Z
try this: --- void main() { for (int i=0; i<1000; i++) { spawn(&thread); } thread_joinAll(); writefln("Collect"); GC.collect(); Thread.sleep(10.seconds); } ---
Comment #2 by undefer — 2018-12-17T13:16:10Z
anonymous4, and.. it doesn't work.
Comment #3 by er.krali — 2019-12-11T14:43:57Z
I think that the issue is that the thread is never joined properly. I have an application that listens to a socket and spawns a new thread for each (very short-lived) incoming connection, and I have to run `joinLowLevelThread` to get a proper cleanup. And for that each running thread has to send back its id to its parent using `Thread.getThis.id`. Also, thread_joinAll doesn't work in my case either because it waits for all the threads... in order. And I happen to have some other long lived threads, so it blocks there and never cleans up anything. Part of the issue is that you can't get the underlying Thread object from `spawn`, so there's no way to join it. The other part, of course, is that this is not taken care of automatically. Incidentally, it also leaks memory like hell, I can see the GC usage continuously growing and no amount of GC.collect or GC.minimize can get rid of it, so the data must be being kept somewhere...
Comment #4 by robert.schadek — 2024-12-07T13:38:58Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17174 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB