Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why make a bool volatile when multithreading in C#?

I understand the volatile keyword in C++ fairly well. But in C#, it appears to take a different meaning, more so related to multi-threading. I thought bool operations were atomic, and I thought that if the operation were atomic, you wouldn't have threading concerns. What am I missing?

https://msdn.microsoft.com/en-us/library/x13ttww7.aspx

like image 539
user2588666 Avatar asked May 16 '15 06:05

user2588666


People also ask

What is the purpose of volatile in C?

C's volatile keyword is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time--without any action being taken by the code the compiler finds nearby.

Why would you declare a field as volatile?

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons.

What is volatile variable in multithreading?

Volatile keyword is used to modify the value of a variable by different threads. It is also used to make classes thread safe. It means that multiple threads can use a method and instance of the classes at the same time without any problem. The volatile keyword can be used either with primitive type or objects.

Does declaring a variable as volatile ensures thread safety?

Unlike synchronized methods or blocks, it does not make other threads wait while one thread is working on a critical section. Therefore, the volatile keyword does not provide thread safety when non-atomic operations or composite operations are performed on shared variables.


1 Answers

I thought bool operations were atomic

They are are indeed atomic.

and I thought that if the operation were atomic, you wouldn't have threading concerns.

That is where you have an incomplete picture. Imagine you have two threads running on separate cores, each with their own cache layers. Thread #1 has foo in its cache, and Thread #2 updates the value of foo. Thread #1 won't see the change unless foo is marked as volatile, acquired a lock, used the Interlocked class, or explicitly called Thread.MemoryBarrier() which would cause the value to be invalidated in the cache. Thus, guaranteeing that you read the most up to date value:

Using the volatile modifier ensures that one thread retrieves the most up-to-date value written by another thread.

Eric Lippert has a great post about volatility where he explains:

The true semantics of volatile reads and writes are considerably more complex than I've outlined here; in fact they do not actually guarantee that every processor stops what it is doing and updates caches to/from main memory. Rather, they provide weaker guarantees about how memory accesses before and after reads and writes may be observed to be ordered with respect to each other.

Edit:

As per @xanatos comment, This doesn't mean that volatile guarantees an immediate read, it guarantees a read on the most updated value.

like image 174
Yuval Itzchakov Avatar answered Sep 20 '22 10:09

Yuval Itzchakov