C++ 检查线程是否应该停止的模式?

C++ 检查线程是否应该停止的模式?,c++,multithreading,C++,Multithreading,线程是否有一个标准模式来检查它是否应该停止工作 这个场景是一个线程正在旋转一个紧密的工作循环,但是如果另一个线程告诉它,它应该停止。我想检查一个原子bool-in-loop条件,但我不确定这是否是一个不必要的性能损失。例如 std::atomic<bool> stop{false}; while(!stop){ //... } std::原子停止{false}; 当(!停止){ //... } 我看不出有任何理由认为bool应该是原子的。实际上,不存在出现比赛状态的可能性。当您

线程是否有一个标准模式来检查它是否应该停止工作

这个场景是一个线程正在旋转一个紧密的工作循环,但是如果另一个线程告诉它,它应该停止。我想检查一个原子bool-in-loop条件,但我不确定这是否是一个不必要的性能损失。例如

std::atomic<bool> stop{false};
while(!stop){
  //...
}
std::原子停止{false};
当(!停止){
//...
}

我看不出有任何理由认为bool应该是原子的。实际上,不存在出现比赛状态的可能性。当您想要停止线程时,首先将变量设置为true,然后发出一个调用来唤醒循环中的阻塞函数(不管您如何做,取决于阻塞调用)


如果阻塞调用恰好在将
stop
设置为true和调用
wakeup\u rx\u thread()
之间唤醒,则循环仍将完成。调用
wakeup\u rx\u thread()
将是不必要的,但这并不重要。

您必须使其原子化(或在旧的C/C++中是易失性的),以确保编译器不会对其进行优化,只测试
停止

如果在循环中调用无法内联的函数(如读取套接字),那么使用非原子bool可能是安全的,但为什么要冒险呢?特别是在这种情况下,原子读取不太可能是性能问题

要使效果最小,您可以执行以下操作:

std::atomic<bool> stop;
void rx_thread() {
  // ...
  while(!stop.load(std::memory_order_relaxed)){
    ..
  }
}
std::原子停止;
无效rx_线程(){
// ...
而(!stop.load(std::memory\u order\u released)){
..
}
}

计时。它有显著的效果吗?有可能的替代方案,但没有循环的细节……我的应用程序的用途是有一个专用的线程读取套接字,但现在我认为这是一个坏主意。但问题是一般性的,考虑到没有人回答,我想没有比原子布更好的方法了。为什么这是一个坏主意?原子布尔值是一个坏主意,因为从套接字读取时,线程无论如何都会阻塞,因此不会读取布尔值。从插座读取不是一个紧密的循环!。。。。无论如何,如果它正在读取套接字数据,为什么还要停止线程呢?设置原子布尔值并让线程执行,如果读取返回,只需丢弃传入的套接字数据,而不是以“常规”方式处理它,或断开套接字连接,或其他任何方式..我可能错了,但我的印象是,根据标准,bools在所有可能的体系结构上都不是原子的,因此存在撕裂的可能性(尽管可能性不大).你说得对,它不是原子的!但是为什么它在这里需要原子的呢?上面的代码中没有任何地方,你需要以原子的方式读写它。我看不出有任何理由认为bool应该是原子的-1.如果没有
原子的
提供的保证,简单的
bool stop
不能保证工作-查看您当前发布的代码-编译器看到
bool stop=false;
并且从未看到任何更改
stop
,因此(!stop)时可以免费省略签入
并将其替换为无限循环。第二,.因此,是的,
原子的
或类似的操作是必要的。请注意,编译器不仅可以自由地执行此操作,还可以为上面的代码执行此操作-如果stop和stop线程是静态的。如果它们是非静态的,则编译器无法轻松执行此操作,因为阻塞调用理论上可能会改变stop或calltop_thread.在C++11之前人们是如何做到的?或者在C中是如何做到的?使用操作系统特定的互斥体?这正是我怀疑存在的那种优化,谢谢。
std::atomic<bool> stop;
void rx_thread() {
  // ...
  while(!stop.load(std::memory_order_relaxed)){
    ..
  }
}