views:

30

answers:

4

Hello

I was wondering, if i have a multi-core processor and i have multiple threads,is it possible that the program will crash if 2 or more threads access a variable at the same time? How can i block temporarily a variable so that simultaneously access is restricted?

Regards, Alexandru Badescu

+1  A: 

it is possible that the program will crash if 2 or more threads access a variable at the same time

It is unlikely that the program will crash. It probably won't behave as you expect it to as it will create a race condition.

How can i block temporarily a variable so that multiple access simultaneously is restricted

Using a lock statement.

Darin Dimitrov
Thanks! But if i lock an object and some stream needs to write to that object, the stream will wait for the object to be unlocked and proceed as normal ? or will it try to access, see it can't access and skip this task ?
Badescu Alexandru
If another thread tries to lock on some object which is currently being locked this other thread will block and wait until the first thread releases the lock.
Darin Dimitrov
Ah you've enlightened me! Regards!
Badescu Alexandru
+2  A: 

You could use the lock keyword, or Interlocked class.

e.g.

public class Foo
{
   private object barLock = new object();
   private int bar;

   public void Add(int x)
   {
        lock (barLock)
        {
            this.bar += x;
        }
   }
}

or

public class Foo
{
   private int bar;

   public void Increment()
   {
        Interlocked.Increment(ref x);
   }
}

I would use the Interlocked class whenever possible, as this is generally the simplest and most efficient (fastest) way to do this, but only certain operations are catered for. For more complex operations, a lock is the way to go.

I would recommend against using the C# volatile keyword as this affects all access to a given field. It's better stick to higher level concepts such as lock or Interlocked.

AdamRalph
+1  A: 

using a lock statement (which is really syntactic sugar for a Monitor.Enter/Exit)

Mitch Wheat
+2  A: 

It won't crash, but it might give the wrong results.

To block, you need to make sure that every access is protected via a lock statement on the same monitor:

private readonly object monitor = new object();
private int sharedVariable;

public void MethodThatSetsVariable()
{
    lock (monitor)
    {
        sharedVariable = 5;
    }
}

public void MethodThatReadsVariable()
{
    int foo;
    lock (monitor)
    {
        foo = sharedVariable;
    }
    // Use foo now
}

Alternatives:

  • Use a volatile variable, although the exact behaviour of volatile is hard to understand. (Well, it's beyond me, anyway.)
  • Use methods on the Interlocked class

Note that both of these are best suited when it's only a single shared variable you're interested in. When you've got to access a set of variables, making sure you only ever see a fully consistent state, locks are the easiest way to go.

Another option - and preferred if at all possible - is to avoid requiring mutable shared state in the first place. It's not always possible, at least without a complete redesign to a messaging-passing architecture - but it's worth aiming for where possible. Immutable types can help to make this easier to achieve.

Jon Skeet