繁体   English   中英

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

[英]How do I terminate a thread in C++11?

我不需要正确终止线程,或者让它响应“终止”命令。 我有兴趣使用纯 C++11 强制终止线程。

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

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

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

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

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

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

std::thread可能具有以下成员函数:

native_handle_type native_handle();

您可以使用它来调用依赖于操作系统的函数来执行您想要的操作。 例如在苹果的操作系统上,这个函数存在并且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)

这个问题实际上具有更深层次的性质,并且对多线程概念的良好理解通常会为您提供有关该主题的见解。 事实上,没有任何语言或任何操作系统为您提供异步突然线程终止的便利,而不会警告您不要使用它们。 所有这些执行环境都强烈建议开发人员,甚至需要在协作或同步线程终止的基础上构建多线程应用程序。 这种常见的决策和建议的原因是它们都是建立在相同的通用多线程模型的基础上的。

让我们比较多处理和多线程概念,以更好地理解第二个概念的优点和局限性。

多处理假设将整个执行环境拆分为由操作系统控制的一组完全隔离的进程。 进程合并并隔离了执行环境状态,包括进程的本地内存和其中的数据以及所有系统资源,如文件、套接字、同步对象。 隔离是过程的一个极其重要的特性,因为它限制了过程边界的故障传播。 换句话说,没有一个进程可以影响系统中任何另一个进程的一致性。 过程行为也是如此,但以较少限制和更加模糊的方式。 在这样的环境中,任何进程都可以在任何“任意”时刻被杀死,因为首先每个进程是隔离的,其次操作系统对进程使用的所有资源有充分的了解,可以在不泄漏的情况下释放所有资源,最后进程将被杀死操作系统并不是在任意时刻,而是在进程状态众所周知的明确定义点的数量上。

相比之下,多线程假设在同一进程中运行多个线程。 但是所有这些线程都共享同一个隔离盒,并且没有任何操作系统控制进程的内部状态。 因此,任何线程都能够更改全局进程状态并破坏它。 同时,线程的状态已知可以安全杀死线程的点完全取决于应用程序逻辑,并且对于操作系统和编程语言运行时都不知道。 因此,在任意时刻终止线程意味着在其执行路径的任意点杀死它,并且很容易导致进程范围内的数据损坏、内存和句柄泄漏、线程泄漏和自旋锁等进程内同步原语留在进程中。关闭状态防止其他线程正在进行。

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

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

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

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

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

也许终止线程? 仅在 windows 中。

WINBASEAPI WINBOOL WINAPI TerminateThread (HANDLE hThread, DWORD dwExitCode);

https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminatethread

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM