parallel.foreach有效,但为什么呢?

use*_*134 7 .net c# thread-safety race-condition parallel.foreach

谁能解释一下,为什么这个程序返回sqrt_min的正确值?

int n = 1000000;

double[] myArr = new double[n];
for(int i = n-1 ; i>= 0; i--){ myArr[i] = (double)i;}

// sqrt_min contains minimal sqrt-value
double sqrt_min = double.MaxValue;

Parallel.ForEach(myArr, num =>
{
double sqrt = Math.Sqrt(num); // some time consuming calculation that should be parallized
if(sqrt < sqrt_min){ sqrt_min = sqrt;}
});
Console.WriteLine("minimum: "+sqrt_min);
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 13

它纯粹运气.有时,当你运行它时,你很幸运,非原子读取和写入double不会导致"撕裂"值.有时你很幸运,非原子测试和套装碰巧正好在比赛发生时设置正确的值.无法保证此程序产生任何特定结果.

  • @ user1193134:我想我已经帮你了.并行ForEach不会神奇地使您的代码线程安全.如果你想要它是线程安全的,*使它线程安全*.你如何选择这样做取决于你; 我不知道你的要求是什么. (3认同)

SLa*_*aks 5

你的代码不安全; 它只能巧合.

如果两个线程if同时运行,其中一个最小值将被覆盖:

  • sqrt_min = 6
  • 线程A: sqrt = 5
  • 线程B: sqrt = 4
  • 线程A进入 if
  • 线程B进入 if
  • 线程B分配 sqrt_min = 4
  • 线程A分配 sqrt_min = 5

在32位系统上,您也容易受到读/写撕裂的影响.

可以Interlocked.CompareExchange在循环中使用它是安全的.