是否有必要在多线程代码中使用原子标志? [英] Is it necessary to have atomic flags in multi-threaded code?

查看:58
本文介绍了是否有必要在多线程代码中使用原子标志?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否真的有必要在多线程代码中使用原子标志.对于这个问题,我重点关注多线程代码中的一个常见情况:通过设置一个标志来停止线程.

I was wondering if it is really necessary to have atomic flags in a multi-threaded code. For this problem, I focus on a common situation in multi-thread code: stopping threads by setting a flag.

让我们假设以下伪代码:

Let's assume following pseudo-code:

is_running = 1;
create_threads(stopper_thread, running_thread_A, running_thread_B, running_thread_C);


stopper_thread         running_thread_A        running_thread_B        running_thread_C
-------------------------------------------------------------------------------------------
 if (x)             |  while(is_running) {   | while(is_running) {   | while(is_running) {
    is_running = 0; |  }                     | }                     | }

在这个伪代码中,所有running_thread_x 线程都使用公共变量is_running 来检查它们是否正在运行.当我们想在 stopper_thread 中停止它们时,我们只需将 is_running 设置为 0.这意味着 is_running 是线程之间的共享资源.在很多编码示例中,人们使用原子变量(例如 C++ 中的 std::atomic_flag)作为 is_running 标志或在临界区访问此变量以提供相互排除访问此变量.

In this pseudo-code, all running_thread_x threads use common variable is_running to check if they are running or not. When we want to stop them in stopper_thread, we just set is_running to 0. this means that is_running is a shared resource between threads. In a lot of coding samples, people use atomic variables (for example std::atomic_flag in C++) for is_running flag or access to this variable in a critical section to provide mutual exclusion in accessing this variable.

但是有必要同步这个标志吗?

我以某种方式相信,在类似于上述示例的情况下,只有 停止操作 作为单个或多个 停止器 线程,实际上没有必要进行同步访问此标志.

I somehow believe that in situations similar to aforementioned example where there is just stopping operation as single or multi stopper thread(s), it is practically not necessary to synchronize access to this flag.

为什么?

因为据我所知,即使我们在多个线程中同时访问 is_running 标志,当我们想停止线程时,这种访问不会阻止从 10 通过停止线程.发生的情况是这种变化可能不会立即反映在正在运行的线程中.但这重要吗?我认为不会,因为如果我们在当前运行线程的迭代中没有从 is_running 读取值 0,你最终会在多次迭代后读取它并且线程将被停止最后.所以设置这个标志最终会停止所有正在运行的线程,但停止可能会延迟一点.

Because as far as I know, even if we have simultaneous access to is_running flag in multiple threads when we want to stop threads, this access does not prevent from setting this flag from 1 to 0 by stopper thread. What happens is that this change may not be reflected in running threads immediately. But is this important? I think not, because if we don't read value 0 from is_running in current iteration of running threads, you will finally read it after few more iterations and thread will be stopped finally. So setting this flag will finally stops all running threads, but stopping may be delayed a little.

你怎么看我的论点?我的论点正确吗?或者我可能错过了我的论证失败的情况?

What do you think about my argument? Is my argument correct? or I may be missing a situation that my argument fails?

推荐答案

发生的情况是这种变化可能不会立即反映在正在运行的线程中.

What happens is that this change may not be reflected in running threads immediately.

实际情况是这是一种未定义的行为.编译器几乎可以对非同步代码执行任何操作.例如允许重写

What happens is that this is an undefined behaviour. The compiler is allowed to do pretty much anything with non-synchronized code. For example it is allowed to rewrite

while(is_running) { }

进入

auto running = is_running;
while(running) { }

当条件在 while 体内没有改变时.

when condition doesn't change inside while body.

因此它将永远循环,无论 is_running 的未来值如何.当 is_running 声明为原子时,不允许这种重写.

And so it will loop forever, regardless of future values of is_running. This rewrite is not allowed when is_running is declared as atomic.

此外,即使编译器不重写此代码,也没有原子性,CPU 仍然可以这样做(它可能从缓存中读取陈旧值,而不是从内存中读取).

Moreover without atomic even if the compiler doesn't rewrite this code, the CPU is still allowed to do it (it may read the stale value from cache, not memory).

人们使用原子的原因是为了避免使用 UB.如果您进行多线程处理,那么您在同步线程时必须使用同步原语.无路可逃.

The reason people use atomics is to avoid UB. If you do multi threading then you have to use synchronization primitives whenever you synchronize threads. There's no escape.

这篇关于是否有必要在多线程代码中使用原子标志?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆