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()
3: bool stopRunning = false;
5: Thread t = new Thread(() =>
7: while (!stopRunning)
12: stopRunning = true;
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.
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.