在 C++11 中从外部终止线程

Posted

技术标签:

【中文标题】在 C++11 中从外部终止线程【英文标题】:Terminate a thread from outside in C++11 【发布时间】:2016-04-26 18:22:15 【问题描述】:

我在我的 C++11 代码中运行多个线程,线程主体是使用 lambda 函数定义的,如下所示。

// make connection to each device in a separate child thread
std::vector<std::thread> workers;
for(int ii = 0; ii < numDev; ii++)
    
    workers.push_back(std::thread([=]()   // pass by value

     // thread body

    ));


// detach from all threads
std::for_each(workers.begin(), workers.end(), [](std::thread &t) 
    t.detach();
);

// killing one of the threads here?

我与所有子线程分离,但在工作向量中保留每个子线程的引用。以后如何在我的代码中杀死其中一个线程?

在here 中发帖建议使用std::terminate(),但我想这对我来说没有用。

【问题讨论】:

How do I terminate a thread in C++11?的可能重复 如果你不合作地杀死一个线程,你怎么能保证你的程序呢? 【参考方案1】:

首先,不要使用原始的std::threads。它们很少是一个好主意。这就像手动调用 newdelete,或者在 io 代码中弄乱原始缓冲区和长度计数器 - 等待发生的错误。

其次,不是杀死线程,而是为线程任务提供一个函数或原子变量,说明工作者何时应该杀死自己。

worker 定期检查它的“我应该死”状态,如果是,它会清理自己并死亡。

然后简单地向工人发出死亡信号,并等待它这样做。

这确实需要在您的工作线程中工作,并且如果它执行了一些无法中断且持续很长时间的任务,则它不起作用。不要做不能中断且持续时间长的任务。

如果您必须执行这样的任务,请在不同的过程中执行,并来回整理结果。但是现代操作系统倾向于使用异步 API,而不是用于 IO 任务的同步 API,如果你小心的话,它们会被中止。

终止处于任意状态的线程会使您的程序进入未知和未定义的执行状态。例如,它可能持有一个互斥锁,并且永远不会让它在标准库调用中使用。但实际上,它可以做任何事情。

通常分离线程也是一个坏主意,因为除非你神奇地知道它们已经完成(很困难,因为你分离了它们),主结束之后发生的事情是由实现定义的。

跟踪线程,就像跟踪内存分配一样,但更重要的是。使用消息告诉线程杀死自己。加入线程以清理它们的资源,可能在包装器中使用条件变量以确保您在线程基本完成之前不加入。考虑使用std::async 代替原始线程,并将std::async 自身包装在进一步的抽象中。

【讨论】:

不是杀死线程,而是为线程任务提供一个函数或原子变量,说明工作者何时应该杀死自己。 好的。我将使用这种方法。

以上是关于在 C++11 中从外部终止线程的主要内容,如果未能解决你的问题,请参考以下文章

c++11的线程,怎么终止

终止线程c ++ 11在读取时阻塞

外部终止线程及阻塞

如何正确的终止正在运行的子线程

在后台线程中删除文件

如何安全地终止线程? (使用指针)C++