I need to have atomic variables in my program. Previously I was using std::atomic
, but the platform in which I\'m working now does not have a g++ com
Volatile variables do NOT imply memory barriers, and do not have the exchange
or compare_exchange_*
operations of std::atomic
. They do avoid the compiler lifting a load into multiple loads on the machine code level (and vice versa, and similar for stores) but that's it.
You may be interested in these articles:
If you do not have std::atomic
, you may want to use boost::atomic, or use the low-level barrier and atomic-operation primitives offered by whatever compiler you're using.
I've seen you asking about GCC in some comments, here you go.
GCC's Built-in functions for atomic memory access
Before C++0x, the language wasn't thread aware, so it did not prevent multiple access. Declaring it volatile will help some, but it won't prevent races.
See http://en.wikipedia.org/wiki/Volatile_variable for more details.
To truly make operations atomic, you'll need to employ whatever locking mechanism your threading library (win32 threads, pthreads, etc) provides.
There's a good summary of the diffs here, from Herb Sutter. In summary (cut and paste):
To safely write lock-free code that communicates between threads without using locks, prefer to use ordered atomic variables: Java/.NET volatile, C++0x atomic, and C-compatible atomic_T.
To safely communicate with special hardware or other memory that has unusual semantics, use unoptimizable variables: ISO C/C++ volatile. Remember that reads and writes of these variables are not necessarily atomic, however.
volatile
basically tells the compiler it can't make assumptions about what is in a particular memory location. For instance
bool test = true;
while(!test)
{
/* do something (e.g. wait) */
}
the compiler might optimize away the whole while
because it assumes test
is always true. If however test
is at some point going to be updated from elsewhere (some hardware or another thread for instance) the we do not want the compiler to assume it knows what is in test
. We can tell the compiler that using volatile
.
As the other answers say, it gives no guarantees about what order things access the memory location in.
P.s. I shamelessly stole that example from somewhere but can't remember where I saw it.
No. volatile
has nothing to do with multithreading. It doesn't enforce a memory barrier (although some compilers might choose to add that anyway), and it makes no guarantees about read/write reordering with respect to non-volatile objects.
volatile
was added to support writing to memory-mapped hardware I/O registers, and such cases, where it is important that your write isn't optimized away, but no precise ordering guarantees wrt. non-volatile reads/wrties are required.
You might also want to read this