Volatile and local

If you’ve done any multithreading programming at all, you must be aware of the volatile modifier. When a field is marked volatile, it tells

1. the JIT compiler that it can’t hoist the field because it may be modified by multiple threads

2. the CLR that the field must be read to and written from with acquire and release semantics.

Given what you’ve read above, the post’s title doesn’t make sense. A local variable, by definition, cannot be accessed from multiple threads. An object referred to by a local variable can be shared among threads, but never the variable itself.

Well, that was true as long as local variables remained just that – local variables. The 2.0 release of C# brought closures to the language, and C# implements capturing of local variables by making them members of a generated class. Now do you see the problem?

  1: public static void Main()
  2: {
  3:     bool stopRunning = false;
  4: 
  5:     Thread t = new Thread(() =>
  6:         {
  7:             while (!stopRunning)
  8:                 Console.WriteLine("Hello");
  9:         });
 10:     t.Start();
 11:     DoSomethingElse();
 12:     stopRunning = true;
 13: }


Nothing out of the ordinary here – I’m creating a thread, passing a lambda to the Thread constructor, and capturing stopRunning inside the lambda.



This code isn’t correct though – for the reasons mentioned in the initial paragraph of this post, stopRunning needs to be declared with the volatile modifier. Unfortunately, you can’t make stopRunning volatile – the compiler complains that local variables cannot be marked volatile.



Oops.



Making stopRunning a member of the class will solve the immediate problem – you can then mark the field volatile, and all is good. However, left at that, it now makes the class non-threadsafe – two threads could call Main, and stopRunning will be shared between them.



I guess this is the price to pay for compiler magic – magic that enables seamless access to local variables from anonymous methods.

4 thoughts on “Volatile and local”

  1. I guess you mistook the C# code for Java code – it is C#, and C# does allow capturing of mutable local variables.

  2. Well, as I see your code doesn’t need volatile keyword because compiler does’t do any optimizations in the thread code.

    so whatever you do, use stopping as you use, or put sttoping out of the main method as volatile, doesn’t have any effect.

    I recommend to you take a look to this article I wrote, is in spanish but you can see the code examples to verify the nature of volatile fields.

    http://juank.black-byte.com/c-explicacion-ejemplo-volatile/

    take a look to “ejemplo 3″ without and with volatile keyword and compare then whith “ejemplo 2″.

    byte!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>