【问题标题】:Understanding std::atomic memory barriers了解 std::atomic 内存屏障
【发布时间】:2017-02-27 13:20:19
【问题描述】:

我想了解 C++ 中内存屏障的工作原理。 例如,我在这种情况下使用 std::atomic:

#include <iostream>
#include <atomic>

int main()
{
    std::atomic<int> a;
    int n = load();//returns 1 or other value written by other thread
    a.store (n, std::memory_order_release);
}

上面的代码在语义上是否与下面的代码相同?

#include <iostream>
#include <atomic>
int main()
{
    std::atomic<int> a;
    int n = load();
    std::atomic_thread_fence(std::memory_order_release);
    n = 100;//assume assignment is atomic
}

如果我是对的,我能否确定所有可以接受内存屏障作为参数的 C++ 函数的行为都是相同的?

【问题讨论】:

  • 你的意思是在 main 函数的第二行,在两个例子中 int n = a.load(std::memory_order_acquire) 和在第二个例子中,第四行:a=100
  • 不,加载函数不是 std::atomic 加载函数。这是一个用户实现的函数,它返回一些数据
  • 这个例子看起来很混乱。第一个摘录清楚地将一个值存储到a 中。但是第二个摘录根本没有引用a,那为什么会出现呢?

标签: c++ multithreading memory-barriers


【解决方案1】:

不,但它相当于:

#include <iostream>
#include <atomic>
int main()
{
    std::atomic<int> a;
    int n = load();
    std::atomic_thread_fence(std::memory_order_release);
    a.store (12345, std::memory_order_relaxed);
    n=100;
}

(尽管该值与您在那里所做的不同)。 必须在栅栏内有一个原子存储。检查“栅栏-栅栏同步”或“栅栏-原子同步”下的条件here。尽管您没有对存储a 设置任何限制,但它将在memory_order_release 内,n 也将如此。这就是栅栏的作用。

【讨论】:

  • 据我了解,您将代码 a.store (12345, std::memory_order_relaxed);用于提供原子分配。我只想知道执行顺序。障碍物是否像我的代码一样影响?
  • @DarkRider memory_order_release 障碍必须在您想要拥有的一切之前。另一方面,memory_order_acquire 的屏障必须在您要同步的所有内容之后。这就是为什么它被称为“栅栏”。这就像你把同步的东西放在一个以release 开始并以acquire 结束的笼子里。这能回答你的问题吗?
  • 我只想知道我何时调用 a.store (n, std::memory_order_release);是在调用 store 函数中的所有操作之前放置了平均障碍吗?我找不到合适的源代码来查看
  • @DarkRider 当你使用屏障时,你不必a.store (n, std::memory_order_release);,因为屏障已经给你了。这样做就足够了:a.store (n, std::memory_order_relaxed);。但无论如何,必须有一些原子存储,不管它是什么,否则屏障将不起作用。请阅读我提供的页面:en.cppreference.com/w/cpp/atomic/atomic_thread_fence
猜你喜欢
  • 2014-05-24
  • 1970-01-01
  • 2016-04-22
  • 1970-01-01
  • 2014-08-04
  • 2015-05-01
  • 2014-02-04
  • 1970-01-01
  • 2015-04-24
相关资源
最近更新 更多