Why ++ operator is not thread safe

Here is a quick hint on how to make your software thread safe. If you want to increment a member of your class you would probably do something like this:

Where val is a member of your class.But this is not thread safe. Doing this involve 4 operations:

  1. Loading the field and put it on the stack
  2. Putting 1 on the stack to increment by 1
  3. Calling add on the stack
  4. Storing the result in the field

Here is the corresponding IL:

The problem is that anywhere between any of the 4 steps another thread can try to do the same thing. For example if a second thread pup in just after the first one is between step 1 and 2 they will both try to increment the same value and store it on the stack. To resolve this problem you can use a lock like this:

But this will generate the following IL:

As you can see there is a lot more code involve to ensure thread safety, A quicker, faster an easier way to do this s to use Interlocked class. This class will use low level OS call to modify the member. Here’s how to use it:

This will be render as two major IL steps:

  1. Load value from the field and put it on the stack
  2. Call Increment

Here is the IL representation of this:

Now every time you will see something++ you will know that this is not thread safe and how to fix it.

One thought on “Why ++ operator is not thread safe

  1. I think you are maybe right in your advice, but I think not really for the reasons given.
    First, IL code is not executed, it is compiled into native code. And unless the CLR compiler is dumber than I think it is, it will compile a ++ of an object member into a single instruction, because the address of the object will already be in a register. Both the 32-bit and 64-bit Intel instruction sets have such an instruction, called INC. Unfortunately, despite that, INC is not guaranteed to be atomic i.e. not thread-safe on a hyperthreaded or multicore CPU.

    Secondly, and it’s kind of a quibble, but
    Interlocked.Increment(ref val);
    does not load the value of val onto the stack, it loads the *address* of val onto the stack, then the called function atomically increments the value at that address.

Leave a Reply