首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用acq/rel顺序推导出两个变量存储/加载的顺序?

如何用acq/rel顺序推导出两个变量存储/加载的顺序?
EN

Stack Overflow用户
提问于 2022-01-25 09:20:37
回答 1查看 61关注 0票数 1

我正在尝试学习C++中涉及原子变量的执行顺序,我有以下代码。

根据优先选择,我的推理如下:

  1. C++在执行时执行1->2顺序,因为在同一线程中获取加载之前,不能移动load/存储。
  2. 当执行与1相同的原因时,C++强制执行3->4顺序。
  3. C++在执行时强制执行2->3顺序 因为2是对y的释放存储,3是从y获得的负载,所以在3之前应该可以看到SO2。因此,2应该在3之前执行,3将读取2的写入结果。
  4. 当执行与3相同的原因时,C++强制执行4->1顺序

从推理1/2/3中,我们可以推导出1 -> 2 -> 3 -> 4的执行顺序,从而打破推理4;从推理1/2/4中可以推导出3 -> 4 -> 1 -> 2的执行顺序,从而破坏推理3。

这里似乎有冲突。

代码语言:javascript
运行
复制
int main() {
    while(true) {
        std::atomic<int> x, y;
        x.store(10);
        y.store(20);
        auto f1 = [&]() {
            int r1 = x.load(std::memory_order_acquire); // 1
            y.store(r1, std::memory_order_release); // 2
        };
        auto f2 = [&]() {
            int r2 = y.load(std::memory_order_acquire); // 3
            x.store(r2, std::memory_order_release); // 4
        };
        std::thread t1(f1);
        std::thread t2(f2);
        t1.join();
        t2.join();
        printf("%d %d\n", x.load(), y.load());
    }
}

-编辑--

我对为什么2必须发生在3点之前的理由:

  1. 从预置,y.store(rel)同步-与y.load(acq)。
  2. 然后,根据偏好,我们可以让y.store(rel)线程间发生-在y.load(acq)之前。
  3. 然后y.store(rel)发生在y.load(acq)之前。
  4. 因此,y.store(rel)必须发生在y.load(acq)之前。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-25 09:25:56

1在2之前发生,3在4之前发生。这部分是正确的。

但是,要使3与2“同步”(和“发生在”之后) 2,它必须成功地读取由2编写的值。

如果它不读取该值(因为它在2之前运行),那么就不会发生同步,并且不对4进行相对于1的排序。在本例中,3被称为“连贯-先有秩序” 2。

同样的情况也适用于从4读取值的1。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70846124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档