Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 证明后减量不是原子的。。。失败_C#_Multithreading_Thread Safety_Linqpad - Fatal编程技术网

C# 证明后减量不是原子的。。。失败

C# 证明后减量不是原子的。。。失败,c#,multithreading,thread-safety,linqpad,C#,Multithreading,Thread Safety,Linqpad,我尝试了一个代码示例,它应该证明后减量操作符不是原子的。代码与我在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

我尝试了一个代码示例,它应该证明后减量操作符不是原子的。代码与我在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--; }
void Main(){
var计数=0;
做{
_x=10000;
对于(int i=0;i<100;i++){
新线程(Go.Start();
}
睡眠(1000);
Console.WriteLine(“Try”+count);
计数++;
}而(x==0);
控制台写入线(x);
}
int x=10000;
void Go(){for(inti=0;i<100;i++)x--}
其思想是,在多个线程上并行递减
\ux
,而不锁定,可能会在所有线程完成后导致
\ux
的值,而不是0

我的问题是,无论我尝试多久,结果总是得到0。 我在两台不同的计算机(都是Windows 7)和两个不同版本的.NET上运行了该代码,它们都给出了相同的结果


我在这里遗漏了什么?

正如Lasse V.Karlsen所建议的那样,我在《代码》中增加了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--; }
void Main()
{
var计数=0;
做{
_x=1000000;
var threads=Enumerable.Range(0,10)。选择(=>newthread(Go)).ToList();
foreach(线程中的变量t)
{
t、 Start();
}
睡眠(1000);
Console.WriteLine(“Try”+count);
计数++;
}而(x==0);
控制台写入线(x);
}
int_x;
void Go(){for(inti=0;i<100000;i++)x--}

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

增加迭代次数,很可能线程完成得太快,以至于在您启动另一个线程之前,前一个线程已经结束,从未并行运行。所以不是100,而是数到100000或更大的数字。@LasseV.Karlsen是的。就这样。我在
Go
中增加了迭代次数,在第一次尝试时得到了非0的结果。谢谢。首先创建线程,然后在循环中启动它们。或者使用游泳池。您只需要几个,而不是1000个。@HenkHolterman:我已经尝试在循环之外创建线程对象,但看起来启动线程的成本比执行100次迭代还要高。