【发布时间】:2017-01-13 10:27:24
【问题描述】:
我遇到了这个问题,想知道在调试和发布模式下出现这种行为的原因。
public static void Main(string[] args)
{
bool isComplete = false;
var t = new Thread(() =>
{
int i = 0;
while (!isComplete) i += 0;
});
t.Start();
Thread.Sleep(500);
isComplete = true;
t.Join();
Console.WriteLine("complete!");
}
【问题讨论】:
-
行为到底有什么不同?
-
如果是 java 我会假设编译器看不到“编译”变量的更新。在变量声明中添加 'volatile' 可以解决这个问题(并使其成为静态字段)。
-
啊,Heisenbug。
-
注意:这就是为什么多线程开发具有互斥锁和原子操作之类的东西。当您开始使用多线程时,您需要考虑一组以前并不明显的额外内存问题。像互斥锁这样的线程同步工具可以解决这个问题。
-
@DavidSchwartz:这当然是允许的。并且编译器、运行时和 CPU允许使该代码的结果与您期望的不同。特别是,C# 不允许进行 bool 访问 nonatomic,但允许将非易失性读取及时向后移动。相比之下,Double 对原子性没有这种限制。在没有同步的情况下在两个不同的线程上进行双重读写是允许被撕裂的。
标签: c#