我正在尝试从this book开始的代码示例,它应该证明post减量运算符不是原子的。代码是我在LinqPad中输入的。
void Main() {
var count = 0;
do {
_x = 10000;
for (int i = 0; i < 100; i++) {
new Thread(Go).Start();
}
Thread.Sleep(1000);
Console.WriteLine("Try "+ count);
count++;
} while (_x == 0);
Console.WriteLine(_x);
}
int _x = 10000;
void Go() { for (int i = 0; i < 100; i++) _x--; }
这个想法是,在没有锁定的情况下在多个线程上并行递减_x
可能会导致_x
的值除了0之外的所有线程都已完成。
我的问题是,无论我多久尝试一次,我总是得到0。 我在两台不同的计算机(包括Windows 7)和两个不同版本的.NET上运行代码,两者都给出了相同的结果。
我在这里缺少什么?
答案 0 :(得分:1)
我在Go
中添加了100000个互动,如Lasse V. Karlsen所建议的那样。代码现在在第一次尝试时按预期工作。我还将线程创建移出循环并减少了线程数,正如Henk Holterman建议的那样。
void Main()
{
var count = 0;
do {
_x = 1000000;
var threads = Enumerable.Range(0,10).Select (_ => new Thread(Go)).ToList();
foreach (var t in threads)
{
t.Start();
}
Thread.Sleep(1000);
Console.WriteLine("Try "+ count);
count++;
} while (_x == 0);
Console.WriteLine(_x);
}
int _x;
void Go() { for (int i = 0; i < 100000; i++) _x--; }
现在代码按预期工作。