Dekker式同步的失败通常是通过重新排序指令来解释的。即,如果我们写为什么C++ 11的acquire_release范围不够用于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
仍然会发生。有没有基于重新排序的解释?我的推理在哪里存在缺陷?