我不需要正确终止线程,也不需要响应“terminate”命令。我有兴趣使用纯C ++ 11强制终止线程。
答案 0 :(得分:112)
您可以从任何线程调用std::terminate()
,您所指的线程将强行结束。
您可以安排在目标线程的对象上执行~thread()
,而不会在该对象上插入join()
或detach()
。这与选项1具有相同的效果。
您可以设计一个具有抛出异常的析构函数的异常。然后安排目标线程在强制终止时抛出此异常。这个问题的棘手部分是让目标线程抛出此异常。
选项1和2不会泄漏进程内资源,但会终止每个线程。
选项3可能会泄漏资源,但部分合作是因为目标线程必须同意抛出异常。
在C ++ 11中(我知道)没有可移植的方法来非合作地杀死多线程程序中的单个线程(即,不会杀死所有线程)。设计这样一个功能没有动力。
std::thread
可能有此成员函数:
native_handle_type native_handle();
您可以使用它来调用依赖于操作系统的功能来执行您想要的操作。例如,在Apple的操作系统上,此功能存在且native_handle_type
为pthread_t
。如果您成功,您可能会泄漏资源。
答案 1 :(得分:34)
std::terminate()
(整个过程)碰巧与@AlexanderVX想到的“终止”同名(1个线程)。
总结:“终止1个线程+强力(目标线程不合作)+纯C ++ 11 =没办法。”
答案 2 :(得分:8)
这个问题实际上具有更深层的性质,对多线程概念的一般理解将为您提供有关此主题的见解。事实上,没有任何语言或任何操作系统为您提供异步突然线程终止的功能,而没有警告不使用它们。所有这些执行环境都强烈建议开发人员,甚至需要在协作或同步线程终止的基础上构建多线程应用程序。这些共同决策和建议的原因是它们都建立在相同的通用多线程模型的基础上。
让我们比较多处理和多线程概念,以更好地理解第二个概念的优点和局限性。
多处理假设将整个执行环境拆分为由操作系统控制的一组完全隔离的进程。进程合并并隔离执行环境状态,包括进程的本地内存和其中的数据以及所有系统资源,如文件,套接字,同步对象。隔离是该过程的一个至关重要的特征,因为它限制了过程边界的故障传播。换句话说,没有一个进程可以影响系统中任何其他进程的一致性。对于过程行为也是如此,但是受限制较少且模糊的方式较多。在这样的环境中,任何进程都可以在任意“任意”时刻被杀死,因为首先每个进程都是隔离的,其次,操作系统对进程使用的所有资源都有完整的知识,并且可以在不泄漏的情况下释放所有进程,最后进程将被终止操作系统并非真正处于任意时刻,而是处于众所周知的过程状态的明确定义点数。
相反,多线程假设在同一进程中运行多个线程。但是所有这些线程都共享相同的隔离盒,并且没有任何操作系统控制进程的内部状态。因此,任何线程都能够改变全局进程状态并破坏它。同时,众所周知线程状态可以安全地杀死线程的点完全取决于应用程序逻辑,并且对于操作系统和编程语言运行时都不知道。因此,任意时刻的线程终止意味着在其执行路径的任意点杀死它,并且很容易导致进程范围内的数据损坏,内存和处理泄漏,线程泄漏和自旋锁以及其他进程内同步原语留在关闭状态阻止其他线程进行。
由于这个,常见的方法是强制开发人员实现同步或协作线程终止,其中一个线程可以请求其他线程终止,并且明确定义的点中的其他线程可以检查此请求并从井启动关闭过程 - 以安全和一致的方式发布所有全球系统资源和本地流程范围资源的定义状态。
答案 3 :(得分:6)
使用OS相关函数终止C ++线程的提示:
std::thread::native_handle()
只能在调用join()
或detach()
之前获取线程的有效本机句柄类型。之后,native_handle()
返回0 - pthread_cancel()
将coredump。
要有效地调用本机线程终止函数(例如pthread_cancel)
),您需要在调用std::thread::join()
或std::thread::detach()
之前保存本机句柄。这样您的本机终结符总是有一个有效的原生句柄。
更多解释请参阅:http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread。
答案 4 :(得分:0)
我猜想需要杀死的线程要么处于任何等待模式,要么处于繁重工作。 我建议使用“幼稚”的方式。
定义一些全局布尔值:
std::atomic_bool stop_thread_1 = false;
将以下代码(或类似代码)放在几个关键点上,以使调用堆栈中的所有函数都返回直到线程自然结束为止。
if (stop_thread_1)
return;
然后停止另一个(主)线程中的线程:
stop_thread_1 = true;
thread1.join ();
stop_thread_1 = false; //(for next time. this can be when starting the thread instead)
答案 5 :(得分:-2)
尝试一下:
Calculator<Input, Output, InputNextStep, Func<Input, Output>>
{
Loop
Break
Cleanup
}