在Windows + VisualC上,易失性读写是否原子? [英] Are volatile reads and writes atomic on Windows+VisualC?

查看:241
本文介绍了在Windows + VisualC上,易失性读写是否原子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此网站上有几个问题,询问是否可以使用 volatile 变量进行原子/多线程访问:请参阅这里此处或此处



现在,C(++)标准一致的回答显然是没有



但是,在Windows& Visual C ++编译器,情况似乎不太清楚。



我最近回答并引用了官方MSDN文档 volatile


Microsoft专用



声明为volatile的对象为(...)




  • 写入volatile对象(volatile write)具有Release语义;
    a对指令序列中写入
    a volatile对象之前发生的全局或静态对象

  • 读取volatile对象(volatile读取)具有Acquire语义;在
    指令中读取易失性存储器之后发生对
    全局或静态对象



这允许将挥发性对象用于内存锁定和释放。





现在,读到这一点,对我来说,一个volatile变量将被MS编译器处理为 std :: atomic



但是,在对我的答案发表评论,用户 Hans Passant 写了MSDN文章是非常不幸的,它是死了的错误。你不能实现一个锁的volatile,甚至与微软的版本。 (...)






请注意: MSDN似乎很鱼腥,因为你通常不能实现锁没有原子交换(也仍然 留下问题wrt。这个MSDN中给出的其他信息的有效性。 文章,特别是针对此处此处。)






此外,还有The Interlocked *函数的文档,特别是 InterlockedExchange 需要一个何时应使用InterlockedExchange? - 不授权回答此功能是只读或只写原子访问所需的)。



此外, volatile 上面以某种方式引用全局或静态对象,其中我会认为真实获取/释放语义应适用于所有值。



返回问题



在Windows上,使用Visual C ++(2005 - 2010),将声明一个(32位?int?)变量为 volatile 允许原子读取和写入这个变量 - ?



对我来说尤其重要的是,它应该在处理器或平台上独立地支持(或不支持)Windows / VC ++运行。



请使用可验证的信息,链接等来备份您的答案。测试用例!

解决方案

是的,它们在windows / vc ++上是原子的(假设你满足对齐要求等等) >

然而,对于锁,你需要一个原子测试和设置,或比较和交换设计或类似,而不只是原子更新或读取。



否则无法在一个不可分割的操作中测试锁定



编辑:如下所述,32位或更低的x86上的所有对齐的内存访问都是原子的。关键点是易失性使得存储器访问有序。 (感谢您在评论中指出这一点)


There are a couple of questions on this site asking whether using a volatile variable for atomic / multithreaded access is possible: See here, here, or here for example.

Now, the C(++) standard conformant answer is obviously no.

However, on Windows & Visual C++ compiler, the situation seems not so clear.

I have recently answered and cited the official MSDN docs on volatile

Microsoft Specific

Objects declared as volatile are (...)

  • A write to a volatile object (volatile write) has Release semantics; a reference to a global or static object? that occurs before a write to a volatile object in the instruction sequence will occur before that volatile write in the compiled binary.
  • A read of a volatile object (volatile read) has Acquire semantics; a reference to a global or static object? that occurs after a read of volatile memory in the instruction sequence will occur after that volatile read in the compiled binary.

This allows volatile objects to be used for memory locks and releases in multithreaded applications.

[emphasis mine]

Now, reading this, it would appear to me that a volatile variable will be treated by the MS compiler as std::atomic would be in the upcoming C++11 standard.

However, in a comment to my answer, user Hans Passant wrote "That MSDN article is very unfortunate, it is dead wrong. You can't implement a lock with volatile, not even with Microsoft's version. (...)"


Please note: The example given in the MSDN seems pretty fishy, as you cannot generally implement a lock without atomic exchange. (As also pointed out by Alex.) This still leaves the question wrt. to the validity of the other infos given in this MSDN article, especially for use cases like here and here.)


Additionally, there are the docs for The Interlocked* functions, especially InterlockedExchange with takes a volatile(!?) variable and does an atomic read+write. (Note that one question we have on SO -- When should InterlockedExchange be used? -- does not authoritatively answer whether this function is needed for a read-only or write-only atomic access.)

What's more, the volatile docs quoted above somehow allude to "global or static object", where I would have thought that "real" acquire/release semantics should apply to all values.

Back to the question

On Windows, with Visual C++ (2005 - 2010), will declaring a (32bit? int?) variable as volatile allow for atomic reads and writes to this variable -- or not?

What is especially important to me is that this should hold (or not) on Windows/VC++ independently of the processor or platform the program runs on. (That is, does it matter whether it's a WinXP/32bit or a Windows 2008R2/64bit running on Itanum2?)

Please back up your answer with verifiable information, links, test-cases!

解决方案

Yes they are atomic on windows/vc++ (Assuming you meet alignment requirements etc or course)

However for a lock you would need an atomic test and set, or compare and exchange instuction or similar, not just an atomic update or read.

Otherwise there is no way to test the lock and claim it in one indivisable operation.

EDIT: As commented below, all aligned memory accesses on x86 of 32bit or below are atomic anyway. The key point is that volatile makes the memory accesses ordered. (Thanks for pointing this out in the comments)

这篇关于在Windows + VisualC上,易失性读写是否原子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆