了解C ++ 11中的`memory_order_acquire`和`memory_order_release` >>

问题描述 投票:0回答:1

我正在阅读the documentation,更具体地说]

memory_order_acquire

:使用此存储顺序执行加载操作受影响的内存位置上的获取操作:无读取或在此加载之前,可以对当前线程中的写入进行重新排序。所有在释放相同原子变量的其他线程中进行写操作是在当前线程中可见(请参阅下面的“发布-获取”顺序)。

memory_order_release:具有此内存顺序的存储操作执行释放操作:当前无读或写线程可以在此商店之后重新排序。当前所有写入线程在获得相同原子的其他线程中可见变量(请参见下面的“发布-获取”排序)并写入带有原子变量的依赖性在其他线程中变得可见消耗相同原子的原子(请参阅下面的发布-使用顺序)

这两位:

来自memory_order_acquire

...在此加载之前,当前线程中的任何读取或写入操作都无法重新排序...

来自memory_order_release

...在此存储之后,当前线程中的任何读取或写入操作都无法重新排序...

它们到底是什么意思?

还有这个例子

#include <thread>
#include <atomic>
#include <cassert>
#include <string>

std::atomic<std::string*> ptr;
int data;

void producer()
{
    std::string* p  = new std::string("Hello");
    data = 42;
    ptr.store(p, std::memory_order_release);
}

void consumer()
{
    std::string* p2;
    while (!(p2 = ptr.load(std::memory_order_acquire)))
        ;
    assert(*p2 == "Hello"); // never fires
    assert(data == 42); // never fires
}

int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
}

但是我不能真正弄清楚我引用的两位在哪里适用。我了解正在发生的事情,但是由于代码很小,我看不到重新排序的位置。

我正在阅读文档,更具体地说是正在阅读memory_order_acquire:具有此存储器顺序的装入操作将在受影响的存储器位置上执行获取操作:无读取...

c++ multithreading
1个回答
0
投票

[如果您为存储使用std::memory_order_relaxed,则编译器可以使用“ -as-if”规则将data = 42;移至存储之后,并且consumer可以看到非空指针并不确定data

如果您使用std::memory_order_relaxed进行加载,则编译器可以使用“视情况”规则将assert(data == 42);移动到加载循环之前。

© www.soinside.com 2019 - 2024. All rights reserved.