c++ - 需要帮助理解 Boost.Atomic Memory 模型 `memory_order_release` 示例

标签 c++ boost atomic memory-model

我正在查看 boost Atomic 文档,发现了以下示例:

atomic<int> a(0);

thread1:
  ... /* A */
  a.fetch_add(1, memory_order_release);

thread2:
  int tmp = a.load(memory_order_acquire);
  if (tmp == 1) 
  {
    ... /* B */
  } 
  else 
  {
    ... /* C */
  }

现在我对 memory_order_release 和 memory_order_acquire 仍然有点困惑。文档将它们描述为:

内存顺序释放

Perform release operation. Informally speaking, prevents all preceding memory operations to be reordered past this point.

内存顺序获取

Perform acquire operation. Informally speaking, prevents succeeding memory operations to be reordered before this point.

即使有了这些例子,我仍然有点困惑。如果有人能解释上述定义的含义以及 A 和 C 如何发生冲突,我将不胜感激?

最佳答案

这些定义意味着 A 中的任何内存操作在存储到 a 之后都不能重新排序(问题中 release 的定义)。并且 B 或 C 中的任何操作都不能先于另一个线程中的 a 加载(问题中 acquire 的定义)。

现在,该示例假设没有其他代码对 a 进行操作,或者至少没有写入 a。如果 B 被执行,则意味着当加载到 tmp 时,a 的值为 1。要使 a 的值为 1,必须先执行 fetch_add(fetch_addload 同步) ,表示A中的代码执行完毕。如果命中该特定代码路径,则操作的顺序为:

A
a.fetch_add(1,memory_order_release);
int tmp = a.load(memory_order_acquire);
B

现在另一个选项是,当 load 发生时,该值仍然为 0。这意味着第一个线程没有执行 fetch_add,但是有无法保证它可能在哪里执行。当线程 2 执行 C 时,A 可能仍在执行(或者它可能还没有开始,或者可能已经完成)。

如果 A 和 B 都访问同一个变量,则不会发生冲突,因为原子保证 B 只能在 A 完成后才能执行。另一方面,C 没有提供这种保证,因此如果 A 和 C 接触同一个变量并且其中至少一个写入该变量,则存在竞争条件。

关于c++ - 需要帮助理解 Boost.Atomic Memory 模型 `memory_order_release` 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19749345/

相关文章:

atomic - 内存映射文件和单个 block 的原子写入

java - 使用原子变量时的内存排序

c - 取消引用指针时的竞争条件

c++ - 选择哪个数学库来转换 LabView 模块

c++ - 延迟加载 crypto++ cryptopp.dll

c++ - GetTempFileName 在 Windows 10 上似乎已损坏

c++ - 需要 C++ boost::optional 的帮助

c++ - OPENCV3 detectAndCompute 中的调试断言失败

c++ - 用于 boost::bimap 查找的基于模板的包装函数无法正常工作

c++ - 如何使用具有相同标签名称的对等值读取 Boost property_map