Dekker 式同步的失败通常通过重新排序指令来解释。即,如果我们写
atomic_int X;
atomic_int Y;
int r1, r2;
static void t1() {
X.store(1, std::memory_order_relaxed)
r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
Y.store(1, std::memory_order_relaxed)
r2 = X.load(std::memory_order_relaxed);
}
然后负载可以与商店重新排序,导致r1==r2==0
.
我期待一个 acquire_release 栅栏来防止这种重新排序:
static void t1() {
X.store(1, std::memory_order_relaxed);
atomic_thread_fence(std::memory_order_acq_rel);
r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
Y.store(1, std::memory_order_relaxed);
atomic_thread_fence(std::memory_order_acq_rel);
r2 = X.load(std::memory_order_relaxed);
}
货物不能移到栅栏上方,仓库不能移到栅栏下方,应防止造成不良后果。
但是,实验表明r1==r2==0
仍然可以发生。对此是否有基于重新排序的解释?我推理的缺陷在哪里?