我想知道,如果我有一个多核处理器并且我有多个线程,如果两个或多个线程同时访问一个变量,程序是否会崩溃?如何暂时阻止变量以便同时限制访问?
此致 Alexandru Badescu
答案 0 :(得分:5)
它不会崩溃,但可能会产生错误的结果。
要阻止,您需要确保通过同一监视器上的锁定语句保护每个访问权限:
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
}
备选方案:
volatile
变量,但volatile
的确切行为很难理解。 (好吧,无论如何,它超出了我。)Interlocked
类请注意,当它只是您感兴趣的单个共享变量时,这两个最适合。当您必须访问一组变量时,确保您只看到完全一致的状态,锁是最简单的方法。
另一种选择 - 如果可能的话,首选 - 是避免首先要求可变共享状态。它并不总是可能的,至少没有对消息传递架构进行彻底的重新设计 - 但是值得在可能的情况下进行瞄准。不可变类型有助于使这更容易实现。
答案 1 :(得分:2)
答案 2 :(得分:2)
您可以使用lock
关键字或Interlocked
类。
e.g。
public class Foo
{
private object barLock = new object();
private int bar;
public void Add(int x)
{
lock (barLock)
{
this.bar += x;
}
}
}
或
public class Foo
{
private int bar;
public void Increment()
{
Interlocked.Increment(ref x);
}
}
我会尽可能使用Interlocked
类,因为这通常是最简单,最有效(最快)的方法,但只能满足某些操作要求。对于更复杂的操作,lock
是可行的方法。
我建议不要使用C#volatile
关键字,因为这会影响对给定字段的所有访问权限。最好坚持更高级别的概念,例如lock
或Interlocked
。
答案 3 :(得分:1)
使用lock语句(这对于Monitor.Enter / Exit来说真的是语法糖)