C# 证明后减量不是原子的。。。失败
我尝试了一个代码示例,它应该证明后减量操作符不是原子的。代码与我在LinqPad中输入的代码相同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
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次迭代还要高。