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

发布于 2024-12-14 19:50:49 字数 689 浏览 0 评论 0原文

我正在尝试本书中的代码示例,该示例应该证明帖子递减运算符不是原子的。该代码是我在 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 上运行了代码,并且都给出了相同的结果。

我在这里缺少什么?

I was trying out a code sample from this book that should demonstrate that the post decrement operator is not atomic. The code is as I have entered it into 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--; }

The idea is that decrementing _x in parallel on multiple threads without locking may lead to a value of _x other then 0 when all the threads have finished.

My problem is that no matter how long I seem to try I always get 0 as a result.
I have run the code on two different computers (both Windows 7) and two different versions of .NET and both give me the same result.

What am I missing here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉生梦死 2024-12-21 19:50:49

按照 Lasse V. Karlsen 的建议,我在 Go 中添加了 100000 次交互。现在,该代码在第一次尝试时就可以按预期工作。我还将线程创建移出了循环,并按照 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--; }

该代码现在可以按预期工作。

I have added 100000 interations in Go as Lasse V. Karlsen has suggested. The code now works as expected on the first try. I have also moved the Thread creation out of the loop and reduced the thread count as Henk Holterman has suggested.

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

The code now works as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文