c++ - 释放语义中的内存操作 - C++11 的内存排序

标签 c++ c++11

我正在尝试理解 C++11 内存排序的 Acquire-Release 语义

我不明白的是以下断言是否会失败:

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

int global_x{0};
std::atomic_int sync{0};
std::atomic_int atm_y{0};

void thread1()
{
    global_x=100;
    atm_y.store(200, std::memory_order_relaxed);
    sync.store(1,std::memory_order_release);
}

void thread2()
{
    while(!sync.load(std::memory_order_acquire)){;}
    assert(atm_y.load(std::memory_order_relaxed) == 200);
    assert(global_x == 100);
}

int main()
{
    global_x=0;
    sync=0;
    atm_y=0;
    std::thread t1(thread1);
    std::thread t2(thread2);
    t1.join();
    t2.join();
}

我知道 sync.store()synchronize-with sync.load() 因为 acquire-release 语义 但这种语义是否保证 release 之前的内存操作将进入内存 (RAM)?

最佳答案

从 Anthony Williams 的“C++ Concurrency in Action”中解释一个非常相似的例子( list 5.8):

从 atm_y 加载的断言永远不会失败,因为对 atm_y 的存储发生在存储同步之前(它们在同一个线程中)。因为要同步的存储与来自同步的加载同步,所以到 atm_y 的存储也发生在来自同步的加载之前,并且通过扩展发生在来自 atm_y 的加载之前。

相同的逻辑适用于对 global_x 的赋值。分配发生在存储同步之前,因此断言永远不会触发。

关于c++ - 释放语义中的内存操作 - C++11 的内存排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46225563/

相关文章:

c++ - 在 C++ 的子类中重载枚举

macos - Mac 中找不到包 'libcrypto'

c++ - 从主类中实例化的另一个类访问主类实例方法

c++ - 索引属性如何返回引用?

c++ - 使用模板将类方法绑定(bind)到特定原型(prototype)

c++11 - 为什么在C++ 0x右值引用的正向定义中使用标识?

c++ - 新分配的先前数据会发生什么变化?

C++ strptime 给出错误的结果

c++ - 访问冲突读取位置 0x00000000 cstrings

c++ - c++11 lambda 真的支持闭包吗?函数变量中存在语义冲突