当前C++0x draft在第291-1.29节和第1111-1112页中声明了以下示例中的内容:
// Thread 1
r1 = y.load(memory_order_relaxed);
x.store(1, memory_order_relaxed);
// Thread 2
r2 = x.load(memory_order_relaxed);
y.store(1, memory_order_relaxed);
结果
r1 = r2 = 1
是可能的,因为每个线程的操作都被放宽并且指向不相关的地址。现在,我的问题是关于以下(类似)示例的可能结果:// Thread 1
r1 = y.load(memory_order_acquire);
x.store(1, memory_order_release);
// Thread 2
r2 = x.load(memory_order_acquire);
y.store(1, memory_order_release);
我认为在这种情况下,结果
r1 = r2 = 1
是不可能的。如果可能,y的负载将与商店同步(因此在之前发生)到y。与x相似,x的负载将发生在存储到x之前。但是y的负载是在存储到x之前(因此也发生在之前)排序的。这创建了一个周期性的事前关系,我认为这是不允许的。 最佳答案
如果我们像阅读代码一样花时间(或者,如果需要的话,指令序列)向下流动,那么我的理解是
换句话说,如果您有类似的代码
acquire
// other stuff
release
那么内存访问可能会从获取/释放对的外部移动到内部,但反之则不行(并且它们也可能不会完全跳过获取/释放对)。
利用问题中第一个示例中宽松的一致性语义,硬件可以对内存访问进行重新排序,以使存储在加载之前进入内存系统,从而允许r1 = r2 = 1。利用第二示例中的获取/释放语义,防止了重新排序,因此r1 = r2 = 1是不可能的。
关于C++ 0x : memory ordering,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2912658/