Proper clean-up of threads


we are using threads to handle accepts from a TServerSocket, i.e. something like

    TSocket *socket = fsServerSocket->Accept();
    TString name(Form("client_%d", socket->GetPort()));
    TThread *handle = new TThread(name.Data(), Handle,
                                  (void*) socket);

The object pointed to by socket is deleted at the end of the function Handle. The threads are saved in a TList fsHandles to check later on the status of the threads and, if the thread is not running anymore, call Delete() of the thread.

However, every new connection increases the amount of virtual memory by 10+ MB, which are not regained when the thread is finished and deleted. This is even the case if the Handle function is a stub one:

void* Handle(void* ptr) { TSocket *socket = (TSocket*) ptr; delete socket; return 0;

This memory consumption is crucial, because these are analysis jobs running on diskless machines without swap and a process limit on virtual memory. We are using this code since nearly 10 years now, but this effect started killing jobs (running out-of-memory) only recently - although I cannot pin down the exact date.

The systems showing this effect are various Linux flavours (recent Debian, Ubuntu, Fedora).

Therefore my question: how to handle and delete threads properly in order to avoid this effect?

Thanks in advance and best regards,

I kind of stumbled upon the reason and I actually don’t know why it worked in the past. The reason is I implicitly used joinable threads and the resources couldn’t be freed until a join. I simply wasn’t aware of the fact that the definition of the thread function as void* or void decides on the detached state and I would not if I didn’t read a older post here mentioning that.

In the User’s Guide it is said, that one should define a function void* func(void*) to be started as thread. However, it is not said that a join is needed in that case. In addition, in the current online reference guide (5.30), the TThread class is missing the second version in the overview and in the detailed list further down in both cases VoidRtnFunc_t is used: … ad:TThread%2
I think, it would be good to point out the difference between void* and void more clearly in the user’s guide.

Best regards,