开发者

Adding a value to a global variable at the same time from multiple threads?

How can I add value to a variable at the same time? If I can what result will be? crash or something e开发者_运维百科lse?

For example:

int a;

so there will be 2 thread to adding value once.


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;
    }
  }
}


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜