thread access to variables in use
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开发者_运维问答
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 ofvolatile
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.
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.
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
.
using a lock statement (which is really syntactic sugar for a Monitor.Enter/Exit)
精彩评论