Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
968 views
in Technique[技术] by (71.8m points)

multithreading - C# bool is atomic, why is volatile valid

In C#, we know that a bool is atomic - then why is it valid to mark it as volatile? what is the difference and what is a good (or even practical) use-case for one versus the other?

bool _isPending;

Versus

volatile bool _isPending; // Is this realistic, or insanity?

I have done some reading here and here, and I'm trying to ensure that I fully understand the inner workings of the two. I want to understand when it is appropriate to use one vs the other, or if just bool is enough.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In C#, we know that a bool is atomic - then why is it valid to mark it as volatile? what is the difference and what is a good (or even practical) use-case for one versus the other?

The supposition of your question is that you believe that volatile makes an access atomic. But volatility and atomicity are completely different things, so stop conflating them.

Volatility is the property that the compiler and runtime are restricted from making certain optimizations involving moving reads and writes of variables forwards and backwards in time with respect to each other, and more generally, with respect to other important events such as starting and stopping threads, running constructors, and so on. Consult the C# specification for a detailed list of how operations may or may not be re-ordered with respect to visible side effects.

Atomicity is the property that a particular operation can only be observed as not started or totally completed, and never "halfway done".

As you can see from the definitions, those two things have nothing whatsoever to do with each other.

In C#, all accesses to references, bools, and integer types of size 4 and smaller are guaranteed to be atomic.

Now, in C# there is some slight non-orthogonality between atomicity and volatility, in that only fields of atomic types may be marked as volatile. You may not make a volatile double, for example. It would be really weird and dangerous to say "we're going to restrict how reads and writes may be optimized but still allow tearing". Since volatility does not cause atomicity, you don't want to put users in a position of thinking that an operation is atomic just because it is also volatile.

You should read my series of articles that explains in far more detail what the differences between these things are, and what volatile actually does, and why you do not understand nearly enough to be using it safely.

https://ericlippert.com/2011/05/26/atomicity-volatility-and-immutability-are-different-part-one/

https://ericlippert.com/2011/05/31/atomicity-volatility-and-immutability-are-different-part-two/

https://ericlippert.com/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three/

https://web.archive.org/web/20160323025740/http://blog.coverity.com/2014/03/12/can-skip-lock-reading-integer/

If you think you understand volatility after reading all that, I invite you to try to solve the puzzle I pose here:

https://web.archive.org/web/20160729162225/http://blog.coverity.com/2014/03/26/reordering-optimizations/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...