我正在尝试在发布-获取订购 https://en.cppreference.com/w/cpp/atomic/memory_order标题下理解这些部分

他们说关于原子负载和存储:



然后关于互斥锁:



第一段似乎说,原子加载和存储(使用memory_order_releasememory_order_acquire)线程B保证可以看到线程A编写的所有内容。包括非原子性的文字。

第二段似乎暗示了互斥锁的工作方式与相同,除了之外,B可见的范围仅限于关键部分中包装的内容,这是否是正确的解释?还是每次写,甚至关键部分之前的内容都对B可见?

最佳答案

我认为以这种方式编写有关互斥量的cppreference引用的原因是,如果您使用互斥量进行同步,则应始终在关键部分内访问用于通信的所有共享变量。
2017年标准在4.7.1中说:

更新:
我想确保我的帖子内容可靠,因为很难在网上找到此信息。感谢@Davis Herring为我指出正确的方向。
标准说
33.4.3.2.11 33.4.3.2.25 中:

(https://en.cppreference.com/w/cpp/thread/mutex/lockhttps://en.cppreference.com/w/cpp/thread/mutex/unlock)
4.6.16 中:

https://en.cppreference.com/w/cpp/language/eval_order
4.7.1.9 中:

https://en.cppreference.com/w/cpp/atomic/memory_order

  • 因此,通过4.7.1.9.1,在随后的锁C之前,将发生互斥锁解锁B线程间。
  • 4.7.1.9.3.2
  • 在互斥锁解锁B之前按程序顺序进行的任何评估A也在C之前在C之前进行线程间交互
  • 因此,在unlock()之后,保证所有先前的写入(即使是关键部分之外的写入)也必须对匹配的lock()可见。

  • 这个结论与现在(过去)实现互斥锁的方式一致,即所有程序顺序的先前加载和存储在解锁之前已完成。 (更准确地说,当在任何线程中通过匹配的锁定操作观察到解锁时,必须先看到存储区。)毫无疑问,这是理论上和实践中公认的释放定义。

    09-25 17:42