I have a program that has multiple threads that read sensor data (with a function from a DLL) and pushes them to a buffer. The thing is, the threads are sleeping in-between with sleep_until()
for different intervals. Can be like 5 mins and longer. Which means, if I try to close the program and wait with join()
, I would have to wait until all threads wake up and notice that they can stop.
Would it be fine to force close them with TerminateThread()
, because the program will exit anyway and release all resources?
I tried it and it seems to work. I am unsure if I am causing problems I am not noticing.
There's already an answer with an alternative and reference to horrors that generally are applicable to TerminateThread
and some of the alternative suggestion.
I want to cover the specific "sits in sleep_until
" / "the program will exit anyway" situation.
First of all, main issue with TerminateThread
is that the thread being terminated might hold an important lock, like memory allocation lock, and sudden termination will result in eventual hang of some code executing in other threads.
The issue with "sits in sleep_until
" is that the sleeper may go out of that state and do some other thing, like memory allocation, in exactly the time you call TerminateThread
. This will be rare, maybe very rare, but still possible situation.
Making sure that the other thread is still sleeping is technically possible, but not easier than using a solution that avoids TerminateThread
. And such a solution would still rely on an implementation detail that sleep_until
goes directly to kernel wait, and neither C++ standard library, nor user-mode Windows API does not do allocations, etc that might be impacted by sudden TerminateThread
in between.
Now regarding "the program will exit anyway"
Assuming you have:
TerminateThread(thd);
exit(0);
There are still atexit
functions and global object destructors. Which may hang if you killed a thread in unlocky moment and they do deallocation. Changing exit
to ExitProcess
only partly addresses that, as DLLs uninitialization is performed even on ExitProcess
.
Safe options to kill a thread and exit could be:
TerminateThread(thd);
__fastfail(0);
or
TerminateThread(thd);
TerminateProcess(GetCurrentProcess(), 0);
The first will not execute anything except the termination instruction, the second will execute some minimum of code that is not likely to be impacted by TerminateThread
.
But then you don't need to terminate a thread in the first place then, just call __fastfail
or TerminateProcess
.