在进行并发编程时,我需要告诉编译器/优化器它可能不会缓存变量的值,也就是说,它可能随时改变.我目前正在使用volatile关键字,但我想知道这是否真的正确?
该标准规定易失性访问可能不会重新排序,如IO调用,但我实际上根本不关心排序,我关心内容.标准中是否有任何内容可以澄清每次访问时都必须加载volatile ?
更重要的是,在这种情况下,我甚至不关心它是否重新排序.我使用栅栏/原子操作来保证我需要的任何订单.
另外,在C++ 0x中,将使用atomic<T>自动给出相同的加载保证(如果我调用load)?或者我是否必须将变量标记为volatile?
重要我对锁定一段代码不感兴趣.我已经使用栅栏来确保订购.我正在谈论对单个基础的访问int(在我正在的平台上假设原子).也就是说,我需要专门告诉GCC优化器a不应该以任何方式缓存变量,因此如果在循环中使用,则必须每次都调用相应的加载指令.
如果volatile不正确,这样做的正确方法是什么?我目前正在使用GCC而不是使用C++ 0x.
答案:基本上预先C++ 0x没有什么可以强制重新加载,并且在某些架构上重新加载甚至可能不够.volatile强烈暗示变量应该重新加载,并且可以在许多体系结构上工作,虽然不是正确的答案,但是目前唯一可用的选项.
关于volatile的问题已经有很多了,但是我没有看到一个特别针对我要问的问题:为并发访问标记变量的正确方法.
恭喜你为自己搞清楚这么多细节.是的,volatile对于多线程编程并不是特别有用,并且应始终首选由特定于平台的多线程库(例如pthreads)提供的构造.
具体来说,您应该使用读写锁:一个可以一次解锁一个作者的对象,排除读者和其他作者,或者由多个读者解锁,排除任何作者.这将包含在任何线程API中.
C++ 0x atomic<T>确实解决了这个问题,volatile除非你正在编写设备驱动程序,否则你永远不需要.但是atomic处于较低级别,您可能会更好地使用读写锁抽象.