并发:C++11内存模型用于多线程环境中共享变量

3
如果一个全局变量在两个不同核心上的2个并发运行的线程之间共享,即使对共享变量的访问受到临界区的控制,仍有数据竞争或意外值的可能吗?我需要声明变量为原子(volatile)吗?每个核心可能在其缓存中具有共享变量的值,当一个线程在其缓存中写入其副本时,另一个不同核心上的线程在1号线程释放锁后可能从其缓存中读取旧值。编译器是否默认为由临界区或互斥锁控制的变量生成volatile读/写的代码?
1个回答

9
如果所有对共享变量的访问都由相同的互斥锁或关键部分保护,则即使线程在不同的核心上,也将避免数据竞争和该变量上出现意外值。互斥锁的锁定和解锁函数将包括必要的同步指令,以确保缓存在处理器核心之间正确同步。在锁定区域内,可以使用普通指令来访问共享变量。
除非您打算在没有互斥锁保护的情况下访问它们,否则无需将共享变量声明为原子变量。

感谢您的清晰解释。在阅读编译器优化和新的内存模型的故事后,我只是想确认一下。还有一个问题,如果我移除关键部分,并将共享变量声明为原子的,因为我只关注读取正确、有效的值。即使使用原子声明,是否仍有可能存在其他线程读取陈旧(但有效)的值?或者编译器会执行强制的内存排序以从另一个缓存中读取最新的值(即易失性读取)? - Abhijit-K
@AbhijitKadam,这实际上是一个全新的问题。使用原子操作的过期值和同步关系比互斥锁要复杂一些。 - edA-qa mort-ora-y
1
这是一个复杂的问题。是的,有可能读取过时的值,但默认情况下有一个原子访问的单一总顺序,所以这不应该成为问题。顺便说一句,volatile访问与原子操作完全独立,不影响内存排序。如果您想了解原子操作,请发布一个新问题。 - Anthony Williams
@Anthony,又创建了一个。等待您的专业意见 https://dev59.com/qWoy5IYBdhLWcg3wCpkz - Abhijit-K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接