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

时间:2016-04-26 18:22:16

标签: multithreading c++11

我在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(),但我想在我的情况下没有用。

1 个答案:

答案 0 :(得分:1)

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

其次,不是杀死线程,而是为线程任务提供一个函数或原子变量,告诉工人何时应该自杀。

工人定期检查它是否应该死?&#34;国家,如果是这样,它就会清理并死亡。

然后简单地通知工人死亡,并等待它这样做。

这确实需要在你的工作线程中工作,并且如果它做了一些不能中断的任务,这个任务会持续很长时间,但它不起作用。不要做那些不能中断并且持续很长时间的任务。

如果必须执行此类任务,请在其他过程中执行此操作,并对来回进行编组。但现代操作系统倾向于使用异步API而不是用于IO任务的同步API,如果你小心的话,它们会被中止。

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

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

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