证明后减法不是原子的...失败

时间:2011-11-10 07:14:16

标签: c# multithreading thread-safety linqpad

我正在尝试从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上运行代码,两者都给出了相同的结果。

我在这里缺少什么?

1 个答案:

答案 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--; }

现在代码按预期工作。