volatile能否用于多线程的数据同步?

阅读更多

volatile能否用于多线程的数据同步(线程安全)?

答案是不能!!

以前网上很多资料说用volatile实现无锁,但这样是行不通的。

 

相关参考:

Why is volatile not considered useful in multithreaded C or C++ programming?

http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming


Stay away from Volatile in threaded code?

https://sites.google.com/site/kjellhedstrom2/stay-away-from-volatile-in-threaded-code

 

When to use volatile with multi threading?

http://stackoverflow.com/questions/4557979/when-to-use-volatile-with-multi-threading

 

Short & quick answer: volatile is (nearly) useless for platform-agnostic, multithreaded application programming. It does not provide any synchronization, it does not create memory fences, nor does it ensure the order of execution of operations. It does not make operations atomic. It does not make your code magically thread safe. volatile may be the single-most misunderstood facility in all of C++. See this, this and this for more information about volatile

On the other hand, volatile does have some use that may not be so obvious. It can be used much in the same way one would use const to help the compiler show you where you might be making a mistake in accessing some shared resource in a non-protected way. This use is discussed by Alexandrescu in this article. However, this is basically using the C++ type system in a way that is often viewed as a contrivance and can evoke Undefined Behavior.

volatile was specifically intended to be used when interfacing with memory-mapped hardware, signal handlers and the setjmp machine code instruction. This makes volatile directly applicable to systems-level programming rather than normal applications-level programming.

The 2003 C++ Standard does not say that volatile applies any kind of Acquire or Release semantics on variables. In fact, the Standard is completely silent on all matters of multithreading. However, specific platforms do apply Acquire and Release semantics on volatile variables.

[Update for C++11]

The C++11 Standard now does acknowledge multithreading directly in the memory model and the lanuage, and it provides library facilities to deal with it in a platform-independant way. However the semantics of volatile still have not changed. volatile is still not a synchronization mechanism. Bjarne Stroustrup says as much in TCPPPL4E:

Do not use volatile except in low-level code that deals directly with hardware.

Do not assume volatile has special meaning in the memory model. It does not. It is not -- as in some later languages -- a synchronization mechanism. Sto get synchronization, use atomic, amutex, or a condition_variable.

[/End update]

The above all applies the the C++ language itself, as defined by the 2003 Standard (and now the 2011 Standard). Some specific platforms however do add additional functionality or restrictions to what volatile does. For example, in MSVC 2010 (at least) Acquire and Release semantics do apply to certain operations on volatile variables. From the MSDN:

When optimizing, the compiler must maintain ordering among references to volatile objects as well as references to other global objects. In particular,

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.

However, you might take note of the fact that if you follow the above link, there is some debate in the comments as to weather or not acquire/release semantics actually apply in this case.

 

 

你可能感兴趣的:(C++)