【发布时间】:2018-06-04 00:31:39
【问题描述】:
我想在线程(gcc、Linux、x86)之间共享一个数据结构。 假设我在线程 A 中有以下代码:
shared_struct->a = 1;
shared_struct->b = 1;
shared_struct->enable = true;
线程 B 是一个周期性任务,它首先检查该结构的 enable 标志。
我认为编译器可以重新排序线程 A 中的写入,因此线程 B 可以看到不一致的数据。我熟悉 ARM 上的内存屏障,但是如何确保 x86 上的写入顺序?有没有比 volatile 更好的方法?
我只想在结构中设置一个一致的状态,将所有内容“刷新”到内存并在最后设置一个启用标志。
【问题讨论】:
-
那根本不是 volatile 的用途。如果有原子标志,则应使用 C11
<stdatomic.h> -
我知道 - 这是一个“副产品”,易失性访问不会重新排序。
-
@AnttiHaapala 原子访问与指令重新排序有什么关系?
-
@Lundin
volatile确实保证写入顺序和读取顺序,但不保证一致性。 -
如果您在结构中将
a、b和enable标记为易失性,则保证每个赋值语句都按照它们出现的顺序执行。每个赋值都是一个完整的表达式,末尾有一个序列点。该标准规定,可变访问不能跨序列点重新排序。如果它们被标记为 volatile,则这些分配将按顺序进行
标签: c gcc x86 pthreads memory-barriers