Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is accessing a variable in C# an atomic operation?

I've been raised to believe that if multiple threads can access a variable, then all reads from and writes to that variable must be protected by synchronization code, such as a "lock" statement, because the processor might switch to another thread halfway through a write.

However, I was looking through System.Web.Security.Membership using Reflector and found code like this:

public static class Membership {     private static bool s_Initialized = false;     private static object s_lock = new object();     private static MembershipProvider s_Provider;      public static MembershipProvider Provider     {         get         {             Initialize();             return s_Provider;         }     }      private static void Initialize()     {         if (s_Initialized)             return;          lock(s_lock)         {             if (s_Initialized)                 return;              // Perform initialization...             s_Initialized = true;         }     } } 

Why is the s_Initialized field read outside of the lock? Couldn't another thread be trying to write to it at the same time? Are reads and writes of variables atomic?

like image 622
Rory MacLeod Avatar asked Aug 13 '08 11:08

Rory MacLeod


People also ask

What are variable in C?

Variables are containers for storing data values. In C, there are different types of variables (defined with different keywords), for example: int - stores integers (whole numbers), without decimals, such as 123 or -123. float - stores floating point numbers, with decimals, such as 19.99 or -19.99.

What is accessing a function in C?

Accessing a function. The user-defined function should be called explicitly using its name and the required arguments to be passed. The compiler refers to the function prototype to check whether the function has been called correctly.

Is function a variable in C?

Calling a C function (aka invoke a function)variable = function_name ( args, ...); The function name must match exactly the name of the function in the function prototype. The args are a list of values (or variables containing values) that are "passed" into the function.


1 Answers

For the definitive answer go to the spec. :)

Partition I, Section 12.6.6 of the CLI spec states: "A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size is atomic when all the write accesses to a location are the same size."

So that confirms that s_Initialized will never be unstable, and that read and writes to primitve types smaller than 32 bits are atomic.

In particular, double and long (Int64 and UInt64) are not guaranteed to be atomic on a 32-bit platform. You can use the methods on the Interlocked class to protect these.

Additionally, while reads and writes are atomic, there is a race condition with addition, subtraction, and incrementing and decrementing primitive types, since they must be read, operated on, and rewritten. The interlocked class allows you to protect these using the CompareExchange and Increment methods.

Interlocking creates a memory barrier to prevent the processor from reordering reads and writes. The lock creates the only required barrier in this example.

like image 175
John Richardson Avatar answered Sep 17 '22 01:09

John Richardson