原子SEQ_CST内存顺序如何实际工作?
例如,有共享变量。
int val;
Cls obj;
原子bool变量充当数据指标。
std::atomic_bool flag = false;
线程1仅设置这些变量。
while (flag == true) { /* Sleep */ }
val = ...;
obj = ...;
flag = true; /* Set flag to true after setting shared variables. */
线程2仅获取这些变量。
while (flag != true) { /* Sleep */ }
int local_val = val;
Cls local_obj = obj;
flag = false; /* Set flag to false after using shared variables. */
我的问题是:
对于
std :: memory_order_seq_cst
,它的默认值为std :: atomic_bool
,是否可以安全地在(...){}
?使用
bool
而不是std :: atomic_bool
是正确的吗?
For example, there are shared variables.
int val;
Cls obj;
An atomic bool variable acts as a data indicator.
std::atomic_bool flag = false;
Thread 1 only set these variables.
while (flag == true) { /* Sleep */ }
val = ...;
obj = ...;
flag = true; /* Set flag to true after setting shared variables. */
Thread 2 only get these variables.
while (flag != true) { /* Sleep */ }
int local_val = val;
Cls local_obj = obj;
flag = false; /* Set flag to false after using shared variables. */
My questions are:
For
std::memory_order_seq_cst
, which is default forstd::atomic_bool
, is it safe to set or get shared variables afterwhile (...) {}
?Using
bool
instead ofstd::atomic_bool
is correct or not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,代码很好,正如Alx23Z所说,如果所有
flag
的负载均为std :: memory_order_acquire
,并且所有商店都是std :: memory_order_release
。std :: memory_order_seq_cst
提供的额外语义仅与观察到两个或更多不同的原子变量之间的载荷和商店之间的排序有关。当您的整个程序只有一个原子变量时,它没有有用的效果。粗略地,想法是获得/发布足以确保对非原子变量的访问确实确实发生在Atomic
flag
之间,并且不泄漏”出去”。更正式的是,您可以使用C ++ 11内存模型公理来证明,鉴于线程1中对象的任何读取,并且在线程2中的任何写入对象,其中一个发生在另一个之前。细节有点乏味,但是关键的想法是,收购负载和发行商店正是您需要获得同步的</em>,这就是您在两个操作之间发生的关系的方式 - 不同的线程。否,如果您将
atomic_bool
替换为bool
,则您的代码具有未定义的行为。然后,您将在不同的线程中读取和编写所有变量,而没有可能会创建同步的静音或原子变量,这就是数据竞赛的定义。Yes, the code is fine, and as ALX23z says, it would still be fine if all the loads of
flag
werestd::memory_order_acquire
and all the stores werestd::memory_order_release
. The extra semantics thatstd::memory_order_seq_cst
provides are only relevant to observing the ordering between loads and stores to two or more different atomic variables. When your whole program only has one atomic variable, it has no useful effect.Roughly, the idea is that acquire/release suffice to ensure that the accesses to your non-atomic variables really do happen in between the load/store of the atomic
flag
, and do not "leak out". More formally, you could use the C++11 memory model axioms to prove that given any read of the objects in thread 1, and any write of the objects in thread 2, one of them happens before the other. The details are a little tedious, but the key idea is that an acquire load and a release store is exactly what you need to get synchronization, which is how you get a happens-before relation between operations in two different threads.No, if you replace the
atomic_bool
with a plainbool
then your code has undefined behavior. You would then be reading and writing all your variables in different threads, with no mutexes or atomic variables that could possibly create synchronization, and that is the definition of a data race.