如何在 C++11 中终止线程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12207684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:01:57  来源:igfitidea点击:

How do I terminate a thread in C++11?

c++multithreadingc++11

提问by Alexander V

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.

我不需要正确终止线程,也不需要让它响应“终止”命令。我对使用纯 C++11 强行终止线程很感兴趣。

回答by Howard Hinnant

  1. You could call std::terminate()from any thread and the thread you're referring to will forcefully end.

  2. You could arrange for ~thread()to be executed on the object of the target thread, without a intervening join()nor detach()on that object. This will have the same effect as option 1.

  3. 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.

  1. 您可以std::terminate()从任何线程调用,并且您所指的线程将强制结束。

  2. 您可以安排~thread()在目标线程的对象上执行,而无需干预join()也不detach()在该对象上。这将具有与选项 1 相同的效果。

  3. 您可以设计一个具有引发异常的析构函数的异常。然后安排目标线程在要强行终止的时候抛出这个异常。这个问题的棘手部分是让目标线程抛出这个异常。

Options 1 and 2 don't leak intra-process resources, but they terminate everythread.

选项 1 和选项 2 不会泄漏进程内资源,但它们会终止每个线程。

Option 3 will probably leak resources, but is partially cooperative in that the target thread has to agree to throw the exception.

选项 3 可能会泄漏资源,但部分合作,因为目标线程必须同意抛出异常。

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.

C++11(我知道)中没有可移植的方式来非合作地杀死多线程程序中的单个线程(即不杀死所有线程)。没有动力设计这样的功能。

A std::threadmay have this member function:

Astd::thread可能有这个成员函数:

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_typeis a pthread_t. If you are successful, you are likely to leak resources.

您可以使用它来调用依赖于操作系统的函数来执行您想要的操作。例如在苹果的操作系统上,这个函数存在并且native_handle_type是一个pthread_t. 如果你成功了,你很可能会泄漏资源。

回答by Nanno Langstraat

@Howard Hinnant's answer is both correct andcomprehensive. 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 @AlexanderVX had in mind (1 thread).

@Howard Hinnant 的回答既正确全面。但是如果读得太快可能会被误解,因为std::terminate()(整个过程)恰好与@AlexanderVX 想到的“终止”具有相同的名称(1 个线程)。

Summary: "terminate 1 thread + forcefully (target thread doesn't cooperate) + pure C++11 = No way."

总结:“终止1个线程+强行(目标线程不配合)+纯C++11=没办法。”

回答by boyang

Tips of using OS-dependent function to terminate C++ thread:

使用依赖于操作系统的函数终止 C++ 线程的技巧:

  1. std::thread::native_handle()only can get the thread's valid native handle type before calling join()or detach(). After that, native_handle()returns 0 - pthread_cancel()will coredump.

  2. To effectively call native thread termination function(e.g. pthread_cancel), you need to save the native handle before calling std::thread::join()or std::thread::detach(). So that your native terminator always has a valid native handle to use.

  1. std::thread::native_handle()只能在调用join()or之前获取线程的有效本机句柄类型detach()。之后,native_handle()返回 0 -pthread_cancel()将核心转储。

  2. 为了有效地调用本机线程终止函数(例如pthread_cancel),您需要在调用std::thread::join()或之前保存本机句柄std::thread::detach()。这样您的本机终止符始终有一个有效的本机句柄可供使用。

More explanations please refer to: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread.

更多解释请参考:http: //bo-yang.github.io/2017/11/19/cpp-kill-detached-thread

回答by ZarathustrA

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.

因此,常见的做法是强制开发人员实现同步或协作线程终止,其中一个线程可以请求其他线程终止,而在明确定义点的其他线程可以检查此请求并从明确定义状态开始关闭程序以安全和一致的方式释放所有全球系统范围的资源和本地流程范围的资源。

回答by Doron Ben-Ari

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)