• Post Reply Bookmark Topic Watch Topic
  • New Topic

Volatile Variable Doubts  RSS feed

 
Vaibhav Gargs
Ranch Hand
Posts: 116
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I understand that volatile variables are always read & written from/to main memory and are not cached. Please correct me if I am wrong.

Consider the following piece of code:



Will above method is thread-safe i.e. free from race conditions?

I have read that volatile variables provide visibility but doesn't guarantee airthmatic operations in thread safe manner.

My doubt is lets say, we have two threads: t1 & t2. Both read the value of x as 0. Now, t1 tries to update the value of x by 1 i.e. 1 so won't it be immediately written to main memory and then read by t2 before updating the value to avoid any race condition?

If not, then, do we need to use volatile variables only in case of reading the variables? We can't use volatile variables if we are updating the variables?
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a difference between synchronization and atomicity. Volatile variables only provide synchronization: when you do some things before accessing a volatile variable, a different thread will also see that those things have happened after it has accessed the volatile variable. This is useful for simple signalling between threads:

In this code, thread A will always print "Goodbye". If keepGoing wasn't volatile, this would not be the case! Even though logically there doesn't seem to be a way for thread A to ever print "Hello", the processor is allowed to rearrange the order of statements, as long as the final result is the same. This restriction only holds for the current thread! Without synchronization, other threads may see that the statements were actually performed out of order. For instance, thread A could see that thread B first set keepGoing to false, and that it only changed the value of text *after* thread A had printed it.

Volatile variables do not provide atomicity. x = x + 1; is actually three operations: Read x, add 1, assign to x. While one thread is busy adding 1, another thread could be reading the old value of x. The only way to get around this problem is by using locks or CAS (compare and set) operations.
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Vaibhav Gargs wrote:Will above method is thread-safe i.e. free from race conditions?

No. While the updates to the variable will be immediately visible to other threads, the updates are not atomic, so one thread can overwrite the update of another. After two threads have run this code, a possible outcome is that the value for x is 1.

If not, then, do we need to use volatile variables only in case of reading the variables? We can't use volatile variables if we are updating the variables?

Yes you can, but only if the reads or writes are already atomic. For instance, in my code above thread A performs atomic reads of keepGoing, while thread B performs atomic writes. That's why it works without locks.
 
Vaibhav Gargs
Ranch Hand
Posts: 116
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:
Vaibhav Gargs wrote:Will above method is thread-safe i.e. free from race conditions?

No. While the updates to the variable will be immediately visible to other threads, the updates are not atomic, so one thread can overwrite the update of another. After two threads have run this code, a possible outcome is that the value for x is 1.


Thank you Stephan!

I am really confused to understand the concept. Will try to capture the scenario as below:


We have 2 threads: t1 & t2. I understand that x = x+1 will be 3 operations: read, update & write. Lets give the steps as below:

1. t1 reads x as 0
2. t1 updates x as 1
3. t2 reads x as 0
4. t2 updates x as  1
5. t1 writes x as 1
6. What will happen to t2 now as t1 has updated the value of x?

Queries
I. When we say that the volatile variables are always read/written from/to main memory, then, where the value of x is stored at steps 2 & 4 above?
2. When the value of x is updated as 1 and written to main memory, won't it reflect immediately to t1? Since there is no cache copy of volatile so how does t1 considers the old value of x?
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let's write out x = x + 1; as the three separate processor instructions first:

Each thread has their own processor context, so treat eax as a different register for each thread. Let's call them eax1 and eax2 for thread A and thread B respectively.

After thread A has performed the instructions on lines 4 and 5, eax1 holds 1, but x is still 0. If thread B manages to perform the instruction on line 4 before thread A performs the instruction on line 6, it will load 0 from main memory to eax2. Now, thread A continues to write eax1 to x, so x is now 1. Thread B adds 1 to its eax2 register, which now holds 1, and then overwrites the 1 in x with the 1 from eax2. So even though two ADD instructions have been performed, the final result of x is still 1.
 
Vaibhav Gargs
Ranch Hand
Posts: 116
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Stephan. It clarifies the query.
 
Vaibhav Gargs
Ranch Hand
Posts: 116
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Suppose we have a simple code snippet:



Lets say, we have 2 threads: t1 & t2 and below is the sequence of steps:

1. t1 reads the value of x
2. t2 reads the value of x
3. t1 updates the value of x as 3 => Will it write to main memory

Will t2 read the value again for x? If not, won't it be an issue since x is updated as 3 while t2 still refers to 1?

If any thread writes a volatile variable to main memory, does it mean all other threads will re-read the value of volatile variables? If yes, how they are signaled about that this value is changed?
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What do you mean by re-read? Threads don't have their own copies of volatile variables, so there's nothing to update. After t1 updates x to be 3, when t2 uses x in some expression the value will be 3.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!