Answers:
您可以std::terminate()
从任何线程进行调用,并且您所引用的线程将强制终止。
您可以安排~thread()
在目标线程的对象上执行,而无需干预join()
或detach()
对该对象执行。这将与选项1相同。
您可以设计一个具有析构函数的异常,该析构函数会引发异常。然后安排目标线程在要强制终止该异常时引发此异常。这方面的棘手部分是使目标线程抛出此异常。
选项1和2不会泄漏进程内资源,但它们会在每次终止时终止线程。
选项3可能会泄漏资源,但部分协作是因为目标线程必须同意引发异常。
在C ++ 11中(我知道),没有一种可移植的方式来非合作地杀死多线程程序中的单个线程(即不杀死所有线程)。没有动机去设计这样的功能。
阿std::thread
可具有该成员函数:
native_handle_type native_handle();
您可能可以使用它来调用依赖于OS的函数以执行所需的操作。例如,在Apple的OS上,此功能存在并且native_handle_type
为pthread_t
。如果成功,则很可能会泄漏资源。
std::terminate
既不调用静态析构函数,也不刷新输出缓冲区,所以释放资源的顺序不明确,也不保证用户可以看到任何数据或将其写入永久存储,甚至一致和完整。
exit()
或abort()
达到相同的整体效果。
@Howard Hinnant的回答既正确又全面。但是,如果读取得太快,可能会被误解,因为std::terminate()
(整个过程)恰好与@AlexanderVX想到的“终止”同名(1个线程)。
摘要:“终止1个线程+强制(目标线程不配合)+纯C ++ 11 =没办法。”
std::terminate()
答案就像一个经典的调皮的Djinn故事;它可以满足OP的所有要求,尽管可能不是他的意思。低调的幽默使我微笑。:-)
这个问题实际上具有更深的性质,并且对多线程概念有很好的理解,通常会为您提供有关此主题的见解。实际上,没有任何语言或操作系统可以为您提供异步突然终止线程的便利,而不会警告您不要使用它们。所有这些执行环境都强烈建议开发人员,甚至要求在协作或同步线程终止的基础上构建多线程应用程序。之所以采用这种通用的决策和建议,是因为它们都是基于相同的通用多线程模型构建的。
让我们比较多处理和多线程的概念,以更好地理解第二种方法的优点和局限性。
多重处理假定将整个执行环境分为由操作系统控制的一组完全隔离的进程。进程合并并隔离了执行环境状态,包括进程的本地内存和其中的数据以及所有系统资源,例如文件,套接字,同步对象。隔离是过程的一个至关重要的特征,因为它限制了过程边界传播的故障。换句话说,没有一个进程可以影响系统中任何其他进程的一致性。对于过程行为也是如此,但限制较少且模糊程度更高。在这种环境下,任何进程都可以在任何“任意”时刻被杀死,因为首先每个进程都是孤立的,其次,
相反,多线程假定在同一进程中运行多个线程。但是所有这些线程都共享同一个隔离盒,并且没有任何操作系统控制进程的内部状态。结果,任何线程都可以更改全局进程状态以及对其进行破坏。同时,众所周知,线程状态可以安全杀死线程的点完全取决于应用程序逻辑,操作系统和编程语言运行时都不知道。结果,在任意时刻终止线程意味着在其执行路径的任意点杀死它,并很容易导致整个进程的数据损坏,内存不足并处理泄漏,
因此,常见的方法是强制开发人员实施同步或协作线程终止,其中一个线程可以请求其他线程终止,而其他在定义明确的线程可以检查此请求并从定义明确的状态启动关闭过程以安全一致的方式释放所有全球系统范围的资源和本地过程范围的资源。
使用依赖于操作系统的函数终止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。
我猜想需要杀死的线程要么处于任何等待模式,要么处于繁重的工作。我建议使用“幼稚”的方式。
定义一些全局布尔值:
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)