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);
}
Run Code Online (Sandbox Code Playgroud)
然后负载可以与商店重新排序,导致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);
}
Run Code Online (Sandbox Code Playgroud)
负载不能移动到栅栏上方,并且商店不能移动到栅栏下方,因此应该防止不良结果.
但是,实验表明r1==r2==0仍然可以发生.是否有基于重新排序的解释?我推理的缺陷在哪里?