我不需要正确终止线程,或者让它响应“终止”命令。我有兴趣使用纯 C++11 强制终止线程。
5 回答
您可以
std::terminate()
从任何线程调用,并且您所指的线程将强制结束。您可以安排
~thread()
在目标线程的对象上执行,而无需干预join()
也不detach()
在该对象上。这将具有与选项 1 相同的效果。你可以设计一个异常,它有一个抛出异常的析构函数。然后安排目标线程在被强制终止时抛出这个异常。这个棘手的部分是让目标线程抛出这个异常。
选项 1 和 2 不会泄漏进程内资源,但它们会终止每个线程。
选项 3 可能会泄漏资源,但部分合作是因为目标线程必须同意抛出异常。
C++11(我知道)中没有可移植的方式来非合作地杀死多线程程序中的单个线程(即不杀死所有线程)。没有设计这样一个功能的动机。
Astd::thread
可能有这个成员函数:
native_handle_type native_handle();
您也许可以使用它来调用依赖于操作系统的函数来执行您想要的操作。例如在 Apple 的操作系统上,这个函数存在并且native_handle_type
是一个pthread_t
. 如果你成功了,你很可能会泄漏资源。
@Howard Hinnant 的回答既正确又全面。但是如果读得太快可能会被误解,因为std::terminate()
(整个过程)恰好与@Alexander V 想到的“终止”(1 个线程)同名。
摘要:“终止1个线程+强制(目标线程不合作)+纯C ++ 11 =没办法。”
我想需要被杀死的线程要么处于任何等待模式,要么正在做一些繁重的工作。我建议使用“幼稚”的方式。
定义一些全局布尔值:
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)
这个问题实际上具有更深入的性质,并且对一般多线程概念的良好理解将为您提供有关该主题的见解。事实上,没有任何语言或任何操作系统可以为您提供异步突然线程终止的设施,而不会警告不要使用它们。所有这些执行环境都强烈建议开发人员甚至要求在协作或同步线程终止的基础上构建多线程应用程序。这种共同决策和建议的原因是它们都建立在相同的通用多线程模型的基础上。
让我们比较多处理和多线程概念,以更好地理解第二个的优点和局限性。
多处理假设将整个执行环境拆分为由操作系统控制的一组完全隔离的进程。进程合并和隔离执行环境状态,包括进程的本地内存和其中的数据以及所有系统资源,如文件、套接字、同步对象。隔离是流程的一个非常重要的特征,因为它限制了流程边界的故障传播。换句话说,没有一个进程可以影响系统中任何另一个进程的一致性。过程行为也是如此,但限制较少且更加模糊。在这样的环境中,任何进程都可以在任何“任意”时刻被杀死,因为首先每个进程都是孤立的,其次,
相反,多线程假设在同一个进程中运行多个线程。但是所有这些线程都共享同一个隔离框,并且没有任何操作系统对进程的内部状态进行控制。结果,任何线程都能够更改全局进程状态并破坏它。同时,众所周知,线程的状态可以安全地杀死线程的点完全取决于应用程序逻辑,并且对于操作系统和编程语言运行时都不知道。因此,线程在任意时刻终止意味着在其执行路径的任意点杀死它,并且很容易导致进程范围的数据损坏、内存和句柄泄漏,
因此,通常的做法是强制开发人员实现同步或协作线程终止,其中一个线程可以请求其他线程终止,并且定义明确点的其他线程可以检查此请求并从定义良好的状态启动关闭程序以安全和一致的方式释放所有全球系统范围的资源和本地进程范围的资源。
使用 OS 相关函数终止 C++ 线程的提示:
std::thread::native_handle()
只能在调用join()
or之前获取线程的有效本机句柄类型detach()
。之后,native_handle()
返回 0 -pthread_cancel()
将核心转储。为了有效地调用本机线程终止函数(例如),您需要在调用或
pthread_cancel()
之前保存本机句柄。这样您的本机终结器始终可以使用有效的本机句柄。std::thread::join()
std::thread::detach()
更多解释请参考:http ://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread 。