3

How can I add value to a variable at the same time? If I can what result will be? crash or something else?
For example:

int a;

so there will be 2 thread to adding value once.

4 Answers 4

6

If you do this in an uncontrolled fashion, it's quite possible that you'll lose data.

Each thread will take three steps:

  • Read the value
  • Increment the copy
  • Store the incremented value

If they both perform the first step roughly together, the result will be an increment of 1 instead of 2.

Additionally, there are memory model issues where one thread may not "see" the write from another thread. Memory models are complex beasts...

Use Interlocked.Increment to perform an atomic increment, which also uses volatile memory access to make sure it always sees what other threads have written.

Sample of broken code:

using System;
using System.Threading;

class Test
{
    const int Iterations = 1000000;

    static int counter;


    static void Main()
    {
        Thread t1 = new Thread(AddLots);
        t1.Start();
        AddLots();
        t1.Join();
        Console.WriteLine(counter);
    }

    static void AddLots()
    {
        for (int i = 0; i < Iterations; i++)
        {
            // Broken!
            counter++;
        }
    }
}

Running on my laptop just now, that showed a result of 1011788.

Change this line:

counter++;

to this:

Interlocked.Increment(ref counter);

and it all works beautifully.

Sign up to request clarification or add additional context in comments.

3 Comments

I wonder what is the minimum possible value for counter to be...(1?)
Use lock (counter) ?
@Kiquenet: Nope, that wouldn't compile - you can only lock via reference types. While taking out a lock would be an alternative, it would be much less efficient than using Interlocked.
6

The behavior when 2 threads add to a shared value without any sort of synchronization is undefined. The write wont't cause any sort of crash. It will just leave the value as the final value as seen by one of the threads

In order to get defined behavior you need to add some sort of synchronization such as a lock.

internal static class Holder {
  static object m_lock = new object();
  static int a;
  internal static void Add(int value) {
    lock (m_lock) {
      a += value;
    }
  }
}

Comments

2

This is not possible - write to the same memory address at the same time from two threads. It would be a race condition not a crash. You can use locking technique (see lock statement) or an other synchronization mechanisms. ALso I would note that .NET Framework provides a set of methods (See Interlocked class) which guarantee that operation will be atomic, there are Add, Increment, Decrement, Exchange, CompareExchange.

4 Comments

can you prove its not possible?
@mecki: you would need a proof that it is possible.
@mekici : just imagine RAM on the hardware level, basically a transistor to store single bit for DRAM, so how you would imagine to switch transistor by two electonic signals in the same time? This even sounds messy...
@HenkHolterman; if i would prove it is possible i didnt ask that :)
0

If you assign values to a variable from two threads it is unpredictable what value the variable will have if you do not guard the variable using thread synchronization techniques. If you want to make sure that both values are added, you need to ensure, only one thread can execute to code in question at a time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.