我最近在C ++ 11中使用线程。现在我正在考虑如何强制停止一个线程。我无法在stackoverflow上找到它,也尝试了这些。
我没有更多的想法。我听说过WinAPI,但我想要一个便携式解决方案。 (这也意味着我不会使用fork())
你能告诉我一个解决方案吗?我真的很想这样做。答案 0 :(得分:6)
在C ++中强制关闭线程的一个最大问题是RAII违规。
当一个函数(以及随后的一个线程)正常完成时,它所保存的所有东西都被函数/线程创建的对象的析构函数清理干净。
记忆得到释放,
OS资源(句柄,文件描述符等)被关闭并返回到OS
锁正在解锁,因此其他线程可以使用它们保护的共享资源
执行其他重要任务(例如更新计数器,记录等)。
如果你粗暴地杀死一个线程(例如,在Windows上通过TerminateThread
),实际上不会发生这些线程,并且程序处于非常危险的状态。
可以使用的一个(不那么)常见模式是注册一个“取消令牌”,如果其他线程要求,您可以监视并正常关闭该线程(一个TPL / PPL)。
之类的东西auto cancellationToken = std::make_shared<std::atomic_bool>();
cancellationToken->store(false);
class ThreadTerminator : public std::exception{/*...*/};
std::thread thread([cancellationToken]{
try{
//... do things
if (cancellationToken->load()){
//somone asked the thred to close
throw ThreadTerminator ();
}
//do other things...
if (cancellationToken->load()){
//somone asked the thred to close
throw ThreadTerminator ();
}
//...
}catch(ThreadTerminator){
return;
}
});
通常,人们甚至不为一个小任务打开一个新线程,最好将多线程应用程序视为并发任务和并行算法的集合。一个为一些长期持续的后台任务打开一个新线程,通常在某种循环中执行(例如,接受传入的连接)。
所以,无论如何,要求取消小任务的案例很少见。
tldr:
是否有可靠的方法强制线程在C ++中停止?
没有
答案 1 :(得分:1)
以下是我的大多数设计的方法:
想想两种线程:
1)小学 - 我打电话给主。
2)后续 - 由main或任何后续线程启动的任何线程
当我在C ++中启动std :: thread&#39;或者在C ++中启动posix线程时:
a)我提供所有后续线程访问布尔值&#34;完成&#34;,初始化为false。这个bool可以直接从main传递(或通过其他机制间接传递)。
b)我的所有线程都有一个常规的心跳&#39;通常带有posix信号量或std :: mutex,有时只有一个定时器,有时只是在正常的线程操作期间。请注意心跳&#39;不是民意调查。
另请注意,检查布尔值非常便宜。
因此,只要主要关闭,它只会将完成设置为true并与后续线程连接。
有时main还会发出后续线程可能正在等待的任何信号量(在加入之前)。
有时,后续线程必须让自己的后续线程知道是时候结束了。
这是一个例子 -
主要启动后续主题:
std::thread* thrd =
new std::thread(&MyClass_t::threadStart, this, id);
assert(nullptr != thrd);
请注意,我将this指针传递给此启动...在此类实例中是一个布尔m_done。
主要关闭:
在主线程中,当然,我所做的只是
m_done = true;
在后续线程中(在本设计中,所有线程都使用相同的关键部分):
void threadStart(uint id) {
std::cout << id << " " << std::flush; // thread announce
do {
doOnce(id); // the critical section is in this method
}while(!m_done); // exit when done
}
最后,在外部范围,main调用连接。
可能需要考虑的是 - 在设计线程系统时,您还应该设计系统关闭,而不仅仅是将其添加。