I don't need to terminate the thread correctly, or make it respond to a "terminate" command. I am interested in terminating the thread forcefully using pure C++11.
You could call
std::terminate()
from any thread and the thread you're referring to will forcefully end.You could arrange for
~thread()
to be executed on the object of the target thread, without a interveningjoin()
nordetach()
on that object. This will have the same effect as option 1.You could design an exception which has a destructor which throws an exception. And then arrange for the target thread to throw this exception when it is to be forcefully terminated. The tricky part on this one is getting the target thread to throw this exception.
Options 1 and 2 don't leak intra-process resources, but they terminate every thread.
Option 3 will probably leak resources, but is partially cooperative in that the target thread has to agree to throw the exception.
There is no portable way in C++11 (that I'm aware of) to non-cooperatively kill a single thread in a multi-thread program (i.e. without killing all threads). There was no motivation to design such a feature.
A std::thread
may have this member function:
native_handle_type native_handle();
You might be able to use this to call an OS-dependent function to do what you want. For example on Apple's OS's, this function exists and native_handle_type
is a pthread_t
. If you are successful, you are likely to leak resources.
std::terminate
neither calls static destructors nor does it flush output buffers, so the order in which resources are released isn't well-defined, nor do you have any guarantee that any of your data is visible to the user or written to permanent store, or even consistent and complete. –
Hindorff exit()
or abort()
to the same overall effect. –
Chrissy @Howard Hinnant's answer is both correct and comprehensive. But it might be misunderstood if it's read too quickly, because std::terminate()
(whole process) happens to have the same name as the "terminating" that @Alexander V had in mind (1 thread).
Summary: "terminate 1 thread + forcefully (target thread doesn't cooperate) + pure C++11 = No way."
std::terminate()
answer is like a classic mischievous Djinn story; it fulfills everything in the OP's wish to the letter, though probably not in the way he meant. The understated humor made me smile. :-) –
Peculiarity Tips of using OS-dependent function to terminate C++ thread:
std::thread::native_handle()
only can get the thread’s valid native handle type before callingjoin()
ordetach()
. After that,native_handle()
returns 0 -pthread_cancel()
will coredump.To effectively call native thread termination function(e.g.
pthread_cancel()
), you need to save the native handle before callingstd::thread::join()
orstd::thread::detach()
. So that your native terminator always has a valid native handle to use.
More explanations please refer to: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .
std::thread::native_handle()
, then perform a detach()
and then execute pthread_cancel()
on that cached native handle! Because, if the thread happened to (unexpectedly) finish in the meanwhile, pthread_cancel()
will be called with a dangling pointer! Instead, just call pthread_cancel()
first, and THEN detach()
the useless thread. –
Pedology I guess the thread that needs to be killed is either in any kind of waiting mode, or doing some heavy job. I would suggest using a "naive" way.
Define some global boolean:
std::atomic_bool stop_thread_1 = false;
Put the following code (or similar) in several key points, in a way that it will cause all functions in the call stack to return until the thread naturally ends:
if (stop_thread_1)
return;
Then to stop the thread from another (main) thread:
stop_thread_1 = true;
thread1.join ();
stop_thread_1 = false; //(for next time. this can be when starting the thread instead)
curl
command (which takes long to execute or something). And this curl command (read libcurl library) is a blocking call in the thread. I don't have a while loop or something to check for stop_thread_1
. –
Friedrich curl_multi_wakeup
and curl_multi_poll
calls. –
Friedrich This question actually have more deep nature and good understanding of the multithreading concepts in general will provide you insight about this topic. In fact there is no any language or any operating system which provide you facilities for asynchronous abruptly thread termination without warning to not use them. And all these execution environments strongly advise developer or even require build multithreading applications on the base of cooperative or synchronous thread termination. The reason for this common decisions and advices is that all they are built on the base of the same general multithreading model.
Let's compare multiprocessing and multithreading concepts to better understand advantages and limitations of the second one.
Multiprocessing assumes splitting of the entire execution environment into set of completely isolated processes controlled by the operating system. Process incorporates and isolates execution environment state including local memory of the process and data inside it and all system resources like files, sockets, synchronization objects. Isolation is a critically important characteristic of the process, because it limits the faults propagation by the process borders. In other words, no one process can affects the consistency of any another process in the system. The same is true for the process behaviour but in the less restricted and more blur way. In such environment any process can be killed in any "arbitrary" moment, because firstly each process is isolated, secondly, operating system have full knowledges about all resources used by process and can release all of them without leaking, and finally process will be killed by OS not really in arbitrary moment, but in the number of well defined points where the state of the process is well known.
In contrast, multithreading assumes running multiple threads in the same process. But all this threads are share the same isolation box and there is no any operating system control of the internal state of the process. As a result any thread is able to change global process state as well as corrupt it. At the same moment the points in which the state of the thread is well known to be safe to kill a thread completely depends on the application logic and are not known neither for operating system nor for programming language runtime. As a result thread termination at the arbitrary moment means killing it at arbitrary point of its execution path and can easily lead to the process-wide data corruption, memory and handles leakage, threads leakage and spinlocks and other intra-process synchronization primitives leaved in the closed state preventing other threads in doing progress.
Due to this the common approach is to force developers to implement synchronous or cooperative thread termination, where the one thread can request other thread termination and other thread in well-defined point can check this request and start the shutdown procedure from the well-defined state with releasing of all global system-wide resources and local process-wide resources in the safe and consistent way.
Maybe TerminateThread? In windows only.
WINBASEAPI WINBOOL WINAPI TerminateThread (HANDLE hThread, DWORD dwExitCode);
C++20 introduced std::jthread
, which internally maintains a stop flag, that can be polled by the thread function to exit itself upon request. But this won't work, if one needs to force stop a thread, that is hanging in a slow system or library call, or, even worse, in a deadlock or similar problem.
On Posix systems, including Linux, Android, iOS and MacOS, force terminating a std::thread
or std::jthread
can be achieved via this C call to the system's threading library:
pthread_cancel(thread.native_handle());
The equivalent call on Windows is:
TerminateThread(thread.native_handle(), 1);
It is safe to call pthread_cancel()
even, if the thread has incidentally just terminated itself before that call: Is it safe to call pthread_cancel() on terminated thread? . However, thread.detach()
or thread.join()
must be called after the cancellation request has been issued. Otherwise, race conditions leading to uncontrolled crashes may occur.
Generally, cancelling a thread is extremely hard to perform safely. Most likely, some resources, including memory, locked mutexes and/or open file descriptors, will not be released correctly. Furthermore, threads hanging in an infinite code loop, are generally not cancelable via pthread_cancel()
, as the cancel is by default deferred to the next call of a system function, that is also a cancellation point. This later behavior can be changed via pthread_setcanceltype()
, but it is almost certain, that doing so leads to even more resource leaks, including the risk of leaving the memory management functions (malloc()
, new
etc.) in a corrupted state.
Nonetheless, especially during application teardown, cancelling blocked threads often can lead to more clean results than calling std::terminate()
, which terminates all threads immediately and doesn't care about destructors of global objects or similar.
You can't use a C++ std::thread
destructor to terminate a single thread in a multi-threads program. Here's the relevant code snippet of std::thread
destructor, located in the thread
header file (Visual C++):
~thread()
{
if (joinable())
std::terminate();
}
If you call the destructor of a joinable thread, the destructor calls std::terminate() that acts on the process; not on the thread, otherwise, it does nothing.
It is possible to "terminating the thread forcefully" (C++11 std::thread) by using OS function. On Windows, you can use TerminateThread. "TerminateThread
is a dangerous function that should only be used in the most extreme cases." - Microsoft | Learn.
TerminateThread(tr.native_handle(), 1);
In order to TerminateThread
to effect, you should not call join()
/ detach()
before, since such a call will nullify native_handle()
.
You should call detach()
(or join()
) after TerminateThread
. Otherwise, as written on the 1st paragraph, on thread destructor std::terminate()
will be called and the whole process will be terminated.
Example:
#include <iostream>
#include <thread>
#include <Windows.h>
void Work10Seconds()
{
std::cout << "Work10Seconds - entered\n";
for (uint8_t i = 0; i < 20; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "Work10Seconds - working\n";
}
std::cout << "Work10Seconds - exited\n";
}
int main() {
std::cout << "main - started\n";
std::thread tr{};
std::cout << "main - Run 10 seconds work thread\n";
tr = std::thread(Work10Seconds);
std::cout << "main - Sleep 2 seconds\n";
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "main - TerminateThread\n";
TerminateThread(tr.native_handle(), 1);
tr.detach(); // After TerminateThread
std::cout << "main - Sleep 2 seconds\n";
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "main - exited\n";
}
Output:
main - started
main - Run 10 seconds work thread
main - Sleep 2 seconds
Work10Seconds - entered
Work10Seconds - working
Work10Seconds - working
Work10Seconds - working
main - TerminateThread
main - Sleep 2 seconds
main - exited
© 2022 - 2024 — McMap. All rights reserved.