volatile to synchronize a variable between threads

I have an int foo variable that is accessed from two threads. Assuming that I have no problems with the race conditions (access is protected by the mutex, all operations are atomic or some other way of protecting against race conditions), there is still the problem of “register caching” (due to the lack of a better name), where the compiler may assume that if a variable is read twice without writing between them, it is the same value and therefore can "optimize" things like:

 while(foo) { // <-may be optimized to if(foo) while(1) do-something-that-doesn't-involve-foo; } 

or

 if(foo) // becomes something like (my assembly is very rusty): mov ebx, [foo]; cmp ebx, 0; jz label; do-something-that-doesn't-involve-foo; do-something-else-that-doesn't-involve-foo; if(foo) // <-may be optimized to jz label2; do-something; 

makes a mark foo how volatile solve this problem? Are changes from one thread guaranteed to reach another thread?

If not, what other way to do this? I need a solution for Linux / Windows (possibly standalone solutions), not C ++ 11.

+7
c ++ c multithreading volatile
source share
3 answers

You need memory barriers.

 MemoryBarrier(); 

or

 __sync_synchronize(); 

Edit: I highlighted the interesting part and the link to the wiki article ( http://en.wikipedia.org/wiki/Memory_barrier#cite_note-1 ) and the related link ( http://www.rdrop.com/users/paulmck/scalability/ paper / whymb. 2010.07.23a.pdf )

Here's the answer to your other question (from Wikipedia): In C and C ++, the volatile keyword was intended to allow C and C ++ programs to directly access I / O with memory mapping. Memory I / Os usually require that reads and writes specified in the source code be performed in the exact order specified without gaps. Omitting or reordering reads and writes by the compiler would disrupt the connection between the program and the device that was accessed using memory-mapped I / O. The C or C ++ compiler cannot change the order of reading and writing to the cells of volatile memory, and also does not allow reading or writing to volatile memory. The volatile keyword does not guarantee a memory barrier to ensure cache consistency. Therefore, the use of "volatile" alone is not enough to use a variable for cross-threading for all systems and processors [1]

Check this out, he gives great explanations on the topic: http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2 http: / /channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

+11
source share

If access is protected by a mutex, you have nothing to worry about. The volatile keyword is useless here. A mutex is a complete memory barrier, and therefore, no object whose address cannot be externally visible can be cached via a mutex lock or unlock calls.

+9
source share

The volatile keyword was originally introduced, indicating that this value can be changed by hardware. This occurs when a hardware device has memory registers or memory buffers. The right approach is to use it only for this purpose.

All modern language synchronization constructs and synchronization libraries do not use this keyword. Application level programmers must do the same.

+1
source share

All Articles