我是专门从内存模型的角度来问的。 http://en.cppreference.com/w/cpp/atomic/memory_order

我问是因为我想知道我是否可以在下面使用std::memory_order_consume:

mLocalMemPtr1和2以及mAtomicMemPtr是指向共享缓冲区的指针。

在生产者线程中,我正在做:

for (int x = 0; x < 10; ++x)
{
    ++mLocalMemPtr1
    *mLocalMemPtr1 = x;       // <========= A
    mAtomicMemPtr.store(mLocalMemPtr1, std::memory_order_release);
}

并在消费者中:
tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
while (tempMemPtr != mLocalMemPtr2)
{
    ++mLocalMemPtr2;
    int test = *mLocalMemPtr2;   // <======== B
    doSomeLongRunningThing(test);
    tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
}

那么,依赖链会进入tempMemPtr-> mLocalMemPtr2-> test-> doSomeLongRunningThing吗?

我特别担心B可能在A之前执行。我知道我可以使用std::memory_order_acquire,但是如果条件语句导致了内存顺序依赖性,那么我可以使用consumption(更轻量级)。

最佳答案

CppReference:

1.10.10:

1.10.9:

基于这些事实,我说mLocalMemPtr2应该同步。但是,仍然存在评估顺序的问题。

if (atomic.load(std::consume) < x)
未指定先评估哪个。无法保证(因为我在标准中找不到),编译器将首先执行消耗操作,刷新共享缓冲区,然后加载atomic x
尚未找到证明操作数是以“虚假”方式求值的证据,我说的是,如果不对原子负载mLocalMemPtr2进行显式分解,它将无法正常工作,CPU可能会读取mLocalMemPtr2所指向的过时的内存值。 memory_order_acquire在这里不会有太大变化,因为mLocalMemPtr2带有数据依赖性。

10-08 08:28