我想知道,如果我有一个多核处理器,并且我有多个线程,如果2个或更多的线程同时访问一个变量,程序可能会崩溃吗?我怎样才能暂时阻止一个变量,以便同时访问受到限制?线程访问正在使用的变量
问候, 亚历Badescu
我想知道,如果我有一个多核处理器,并且我有多个线程,如果2个或更多的线程同时访问一个变量,程序可能会崩溃吗?我怎样才能暂时阻止一个变量,以便同时访问受到限制?线程访问正在使用的变量
问候, 亚历Badescu
它是可能的,如果2个或更多的线程在同一时间
这是不可能的,程序会崩溃访问变量,程序会崩溃。它可能不会像你期望的那样表现,因为它会造成竞争状况。
我怎样才能阻止暂时一个变量,以便同时使多个访问限制
您可以使用lock
关键字或Interlocked
类。
例如
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
。
使用lock声明(这实在是语法糖的Monitor.Enter /退出)
它不会崩溃,但它可能会给出错误的结果。
要阻止,你需要确保每一个访问是通过一个锁声明保护的一台监视器上:
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
类的使用方法注意,这两个是最适合当它只是一个单一的共享变量,你有兴趣。当你必须访问一组变量,确保你只能看到完全一致的状态,锁是最简单的方法。
另一种选择 - 和如果在所有可能优选的 - 是为了避免需要在第一位置可变的共享状态。这并不总是可能的,至少在没有对消息传递架构进行完全重新设计的情况下 - 但是在可能的情况下,这是值得的。不可变的类型可以帮助更容易实现。
在特殊情况下,在任何线程启动之前初始化变量,并且线程只读取变量,则不需要任何同步。 – Dialecticus 2010-10-31 10:27:10