我想知道是否必须使用原子整数。
我有一个循环,看起来类似于这样:
struct loop {
volatile int loop_variable;
volatile int limit;
}
for (int i = loop.loop_variable ; i < loop.limit ; loop.loop_variable++) {
}
然后另一个线程执行以下操作:
loops.loop_variable = loops.limit;
并发问题需要解决内存屏障的问题。
这是线程安全的吗?
存在数据竞争的汇编代码在这两行之间:
// loop.loop_variable = loop.limit;
movl 4+loop.0(%rip), %eax
movl %eax, loop.0(%rip)
而且
// for (int i = loop.loop_variable ; i < loop.limit ; loop.loop_variable++)
movl loop.0(%rip), %eax
movl %eax, -4(%rbp)
jmp .L2
.L3:
movl loop.0(%rip), %eax
addl $1, %eax
movl %eax, loop.0(%rip)
.L2:
movl loop.0(%rip), %eax
cmpl $99999, %eax
jle .L3
movl $0, %eax
可能存在数据竞争的地方是
movl loop.0(%rip), %eax
addl $1, %eax
movl %eax, loop.0(%rip)
因为增加循环变量需要三个指令,但只需要一个指令将循环变量覆盖到限制。
loop
的结构体(可能是类型为struct loop
的结构体?),然后一些代码查看loops[0]
。它们是指同一个东西吗?(如果不是,答案可能会更容易;-)) - psmearsvolatile
没有豁免数据竞争规则。同时写入/读取volatile
变量与没有使用volatile
是一样的数据竞争,并且行为也同样未定义。在<stdatomic.h>
存在之前的旧代码会使用volatile
,因为它是最接近的东西,并且如果您对编译器的优化了解得很多,它会大多数情况下工作。但在现代时代不合适。 - Nate Eldredge