c++ - 与 C++ 原子内存栅栏同步

标签 c++ multithreading atomic memory-barriers stdatomic

我有一个关于使用内存栅栏同步下面代码的问题。

std::atomic<int> a = 0;
std::atomic<int> b = 0;

void increase_b() {
  std::atomic_thread_fence(std::memory_order_release);
  b.store(1, std::memory_ordered_relaxed);
}

bool diff() {
  int val_a = a.load(std::memory_ordered_relaxed);
  int val_b = b.load(std::memory_ordered_relaxed);
  return val_b > val_a;
}

void f1() {
  increase_b();
  std::atomic_thread_fence(std::memory_order_seq_cst);
}

void f2() {
  std::atomic_thread_fence(std::memory_order_seq_cst);
  bool result = diff();
}

int main() {
  std::thread t1(f1);
  std::thread t2(f2);
  t1.join(); t2.join();
}

假设 t1 已经完成了 f1 然后 t2 刚刚开始了 f2,t2 会不会 看到 b 递增了吗?

最佳答案

您的代码过于复杂。 a=0永远不会改变,所以它总是读作 0。你还不如只拥有 atomic<int> b=0;只有一个负载只返回 b.load .

Assume t1 has finished f1 and then t2 just started f2, will t2 see b incremented?

除非您输入 t1.join(),否则您无法检测到时间是这样计算的领先 std::thread t2(f2); build 。这将要求线程 2 中的所有内容都排在线程 1 中的所有内容之后。(我认为即使在 f1 的末尾没有 seq_cst 栅栏,但这也无妨。我认为 thread.join 确保所有内容都在线程在 thread.join 之后可见)

但是,是的,这种排序可能是偶然发生的,当然它会起作用。

在 C++ 术语中甚至不能保证这是一个有意义的条件。

但对于大多数(所有?)实际实现来说,这是可能发生的事情。还有一个 thread_fence(mo_seq_cst)将编译为一个完整的屏障,该屏障会阻塞该线程,直到存储提交(对所有线程全局可见)。因此执行不能离开 f1,直到其他线程的读取可以看到 b 的更新值。 . (C++ 标准根据创建同步关系来定义排序和栅栏,而不是根据编译到刷新存储缓冲区的完整屏障来定义。该标准没有提到存储缓冲区或 StoreLoad 重新排序或任何 CPU 内存 -订购东西。)

给定综合条件,线程实际上是按顺序排列的。就像所有事情都在一个线程中完成一样。


diff() 中的负载没有订购wrt。彼此因为他们都是mo_relaxed .但是a从未被任何线程修改过,所以唯一的问题是是否 b.load()甚至可以在线程开始之前发生,在 f1 之前商店是可见的。在实际实现中它不能,因为“然后 t2 刚刚开始 f2”的意思。 如果它可以加载旧值,那么你就不能说“然后”,所以这几乎是一个重言式。

thread_fence(seq_cst)在负载并没有真正帮助任何事情之前。我想它会停止 b.load()从使用线程启动机制重新排序。

关于c++ - 与 C++ 原子内存栅栏同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58208837/

相关文章:

c++ - Dijkstra 算法中的优先级队列

java - 无法在繁重的进程下更新 Swing 组件

c++ - 忙于轮询 std::atomic - msvc 优化了循环 - 为什么以及如何防止?

c++ - 错误 : Initializing Argument 1 of

c++ - 更好的编译器警告?

c# - ASP.NET在运行时显示和隐藏图像

multithreading - 通过计数测试信号量

python - 在 Django 中以原子方式比较交换模型字段

C - 访问整数变量时的安全性 : 1 writer, N 读者

c++ - 读取 fopen 打开的二进制文件 ("ab") (add,binary)