2

I am trying to understand the usage of volatile keyword, so I have written a small example where I was thinking to use Volatile keyword, but currently I am getting the same behavior either I use Volatile keyword or I don't use it.

Following is the code which I am running and I expected the Thread t2 keep executing, even if t1 was updating the ExitLoop property

namespace UsageOfVolatileKeyword
{
    class Program
    {
        static void Main()
        {
            Test t = new Test();

            Thread t2 = new Thread(() => { while (!t.ExitLoop) { Console.WriteLine("In loop"); } });
            t2.Start();

    Thread t1 = new Thread(() => t.ExitLoop = true);
            t1.Start();

            t2.Join();

            Console.WriteLine("I am done");

            Console.ReadLine();
        }
    }

    class Test
    {
        private bool _exitLoop = false; //I am marking this variable as volatile.

        public bool ExitLoop
        {
            get { return _exitLoop; }
            set { _exitLoop = value; }
        }
    }
}

It will be nice if somebody can help me understand what wrong I am doing and what's the proper usage of Volatile keyword is.

svick
  • 236,525
  • 50
  • 385
  • 514
user1570094
  • 169
  • 1
  • 3
  • Are you building debug or release? Is a debugger attached? What JITter architecture and version? – SLaks Jul 01 '13 at 03:06
  • 1
    I don't see the volatile keyword being used here. Are you release or debug compiling? – Haney Jul 01 '13 at 03:13
  • 4
    Are you using an x86 machine? On x86 it is quite difficult to make a situation where volatile behavior is observably different than non-volatile behavior. – Eric Lippert Jul 01 '13 at 05:51
  • If you want an example where `volatile` matters, see the thread [Illustrating usage of the volatile keyword in C#](http://stackoverflow.com/questions/133270/). – Jeppe Stig Nielsen Jul 01 '13 at 08:37
  • On a side note.. volatile is evil http://www.bluebytesoftware.com/blog/2010/12/04/SayonaraVolatile.aspx – Lorenzo Dematté Jul 01 '13 at 08:55
  • I am using x64 machine with release build. I have commented the line in my code example where I made the variable as Volatile, I tried marking it volatile but there was no change in behavior. – user1570094 Jul 01 '13 at 17:04

3 Answers3

3

At a high level, volatile is a marker to the compiler "Make no assumptions about the state of this variable". Essentially you would use it to indicate that either multiple threads or perhaps part of the computer itself might be changing this memory location. For example you might map something to the UART data register on your serial port. When you read this variable, it's value is whatever is in the hardware.

If you don't tell the compiler that this variable is volatile, it might assume that if you set it to true and then use it some point later in the code, that this variable is still true and use some constant folding logic to optimise the code.

Spence
  • 28,526
  • 15
  • 68
  • 103
1

Have you referred http://msdn.microsoft.com/en-us/library/x13ttww7(v=vs.71).aspx ?

variable mentioned with volatile to get no-cached value according recent CPU instruction and no compiler optimization during compilation.

In your case, I think CPU did context switch effectively and flag was consistent (with/out flag). I think we can see some different when there are many multiple threads and cpu was engaged in switching

You also refer the following thread Why is volatile needed in C? which referred in c about OS level internals

Community
  • 1
  • 1
bhaskar
  • 38
  • 2
1

The reason why you do not observe a difference is because Console.WriteLine already generates a memory barrier making volatile redundant in this particular scenario. It is also critical that you do these kinds of tests using a release build and running the application without the debugger attached. Look at my answers here and here, but especially here for examples and explanations on how to reproduce this.

Community
  • 1
  • 1
Brian Gideon
  • 47,849
  • 13
  • 107
  • 150