我正在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?
我从所有子线程中分离出来,但是在worker向量中保留了每个子线程的引用。以后如何在代码中杀死其中一个线程?
here中的帖子建议使用
std::terminate()
,但我想在我的情况下它没有用。
最佳答案
首先,不要使用原始的std::thread
。他们很少是一个好主意。就像手动调用new
和delete
一样,或者在io代码中弄乱原始缓冲区和长度计数器-错误等待发生。
其次,与其杀死线程,不如给线程任务提供一个函数或原子变量,该函数或原子变量说明 worker 何时应该杀死自己。
worker 定期检查其“我应该死”状态,如果是,它会自行清理并死亡。
然后只需发出信号通知 worker 死亡,然后等待死亡即可。
这确实需要您的工作线程中的工作,并且如果它执行了一些长时间无法中断的任务,那么它将无法正常工作。不要执行无法中断且持续时间很长的任务。
如果您必须执行此任务,请以其他过程执行,然后将结果来回编码。但是现代操作系统倾向于具有异步API,而不是用于IO任务的同步API,如果谨慎操作,它们很容易被中止。
在线程处于任意状态时终止线程会将您的程序置于未知且不确定的执行状态。例如,它可能持有一个互斥锁,并且从不让它进入标准库调用。但是实际上,它可以做任何事情。
通常,分离线程也是一个坏主意,因为除非您神奇地知道它们已经完成(很难,因为您已经分离了它们),否则在实现主端之后会发生什么是已定义的。
像跟踪内存分配一样,也要跟踪线程,但是还要注意。使用消息告诉线程杀死自己。加入线程以清理它们的资源,可能在包装器中使用条件变量以确保您在基本完成线程之前不加入。考虑使用std::async
代替原始线程,并将std::async
自身包装在进一步的抽象中。
关于multithreading - 在C++ 11中从外部终止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36872859/