优雅地停止一个std ::线程?

问题描述:

我有一个工作人员std::thread,我希望它的主循环检查是否有其他线程告诉它停止循环并退出。
什么是一个很好的跨平台方式来做到这一点? boost是否为它提供了一些事件对象?
正在使用只是一个bool认为线程安全?优雅地停止一个std ::线程?

+0

你所说的“使用”这里是什么意思?一般来说,答案总是“否”:除'atomic'之外的任何类型本质上都是线程安全的。 – 2011-06-02 12:13:36

+0

锁('std :: mutex')不适合这个。不幸的是,C++ 0x并没有继承'boost :: thread :: interrupt',这是非常遗憾的。看[这些](http://stackoverflow.com/questions/2845704/how-to-interrupt-a-waiting-c0x-thread)[two](http://stackoverflow.com/questions/2790346/c0x-thread - 中断)问题。 – 2011-06-02 12:27:19

+1

@Tomalak:请解释使用互斥锁的问题。这似乎是最简单和最明显的解决方案。 – 2011-06-02 12:31:35

..以及它依赖。线程在做什么?它阻塞任何东西,I/O,sleep还是其他一些API?

如果它只是CPU套住所有不要紧究竟何时停止停止并退出,然后只使用一个布尔时间。在这种情况下,锁定'stopAndExit'布尔值没有意义。

如果工作线程在一个循环中没有将其读为真,那么可能它应该,因为缺乏原子性,它会在下一次得到它。为什么在不需要时执行锁定/ API调用?从用户获取/释放同步对象的内核级调用将花费时间与简单的“if(stop)exit”相比,浪费了每个可用于计算的循环的时间,或者在CPU中执行的任何操作,绑定线程。

它是跨平台的

问候, 马丁

+3

+1为了让人们认为如果昂贵的同步方法真的需要所有的 时间。 – 2011-06-02 13:30:07

+9

我不明白这可以如何保证工作。如果没有内存屏障或易失性读取语义,对于编译器是否有效地优化了寄存器中变量的值?在这种情况下,它永远不会看到更新。我可以告诉你,这种类型的问题**绝对存在于.NET中(如果一个多线程程序经常检查一个布尔条件,它可能会进入一个无限循环,即使它现在实际上是'真',因为它是从另一个线程更新的)。 – bobbymcr 2011-12-25 20:28:48

+0

@bobbymcr - 尝试使用除了非常微不足道的线程之外的任何东西,专门用于显示此问题。这不会发生在英特尔上,我不会在Spark上发生,它不会发生在我曾经用过的任何事情上。这种情况不会发生,因为如果你的呼吸声太大,寄存器会在驱动程序中断,函数调用中溢出到L1缓存中。 – 2013-04-07 22:33:22

你可能有一个std :: mutex在主线程和你的工作线程之间共享。

您的工作线程可以在开始任何工作并间歇性释放之前获取std :: mutex :: try_lock。当主线程想要关闭工作线程时,可以锁定该互斥锁。你的工作线程可以使用try_lock检测到这个并退出

+4

扭转它可能的性能好处?主线程持有锁,工作线程尝试(非阻塞)在循环开始时获取它,成功时退出。每次都释放循环,主线程不必坐在等待循环完成,如果它有其他的东西要做。 – 2011-06-02 12:29:08

std :: mutex,它的亲属是核心机制。 std :: lock_guard和unique_lock在此基础上构建,而std :: condition_variable则适用于此目的。

正如你所说的boost,你可以使用boost :: thread。

在你的情况下,启动一个线程后,你可以使用interrupt()方法来中断它。接收线程可以用boost :: this_thread :: interruption_point()方法检查中断请求。如果有中断请求,这将导致线程退出,否则它将忽略它。

您可以查看这里的文档: Boost Thread Documentation

+0

请注意,std :: thread基于Boost线程设计[link] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2184.html - 所以可以说std会更便携(尽管目前在支持的平台上可能没有什么区别)。 – holtavolt 2011-06-02 13:03:01

+2

std :: thread从中删除了'interrupt'。 :-( – 2011-06-02 13:52:23

+0

@Howard你是否知道它为什么被删除,或者更可怕:为什么C++ 14/17仍然没有它? – rubenvb 2017-06-03 23:10:42