Mar*_* Ba 11 c++ atomic volatile memory-fences visual-c++
有一对夫妇在这个网站,询问使用是否问题volatile变量原子/多线程访问是可能的:见这里,这里,还是这里的例子.
现在,符合C(++)标准的答案显然没有.
但是,在Windows和Visual C++编译器上,情况似乎并不那么清楚.
微软特定
声明为volatile的对象是(...)
- 对volatile对象的写入(volatile write)具有Release语义; 对全局或静态对象的引用?在编译二进制文件中的易失性写入之前,将在写入指令序列中的易失性对象之前发生这种情况.
- 读取volatile对象(volatile read)具有Acquire语义; 对全局或静态对象的引用 ?在读取编译二进制文件中的易失性读取之后,将在读取指令序列中的易失性存储器之后发生这种情况.
这允许volatile对象用于多线程应用程序中的内存锁定和释放.
[强调我的]
现在,读到这一点,在我看来,MS编译器将处理一个易变量变量,就像std::atomic即将推出的C++ 11标准一样.
然而,在对我的回答的评论中,用户Hans Passant写道:"那篇MSDN文章非常不幸,这是错误的.你不能用volatile来实现锁定,甚至不能使用微软的版本.(...)"
请注意:MSDN中给出的示例看起来很可疑,因为您通常无法在没有原子交换的情况下实现锁定.(正如亚历克斯所指出的那样)这仍然留下了问题.有关此MSDN文章中给出的其他信息的有效性,特别是对于此处和此处的用例.)
此外,还有Interlocked*函数的文档,尤其是InterlockedExchange带有volatile(!?)变量并进行原子读取和写入.(注意我们在SO上有一个问题 - 何时应该使用InterlockedExchange? - 没有权威性地回答是否需要这个函数来进行只读或只写原子访问.)
更重要的是,volatile上面引用的文档以某种方式暗示"全局或静态对象",我认为"真正的" 获取/释放语义应该适用于所有值.
在Windows上,使用Visual C++(2005 - 2010),将声明一个(32位?int?)变量volatile允许原子读取和写入此变量 - 或不?
对我来说特别重要的是,它应该独立于程序运行的处理器或平台而在Windows/VC++上保存(或不保存).(也就是说,无论是在Itanum2上运行的WinXP/32bit还是Windows 2008R2/64bit都有关系?)
请用可验证的信息,链接,测试用例备份您的答案!
是的,它们在windows/vc ++上是原子的(假设你符合对齐要求等或课程)
但是对于锁定,您需要进行原子测试和设置,或者比较和交换instuction或类似的,而不仅仅是原子更新或读取.
否则,没有办法测试锁并在一个不可分割的操作中声明它.
编辑:如下所述,无论如何,32位或更低版本的x86上的所有对齐内存访问都是原子的.关键是volatile使得内存访问有序.(感谢您在评论中指出这一点)
| 归档时间: |
|
| 查看次数: |
4615 次 |
| 最近记录: |