首页 > 解决方案 > 并行代码中的多样化输出

问题描述

它以与 0.1、0.2、1、2.3 等相同的概率打印正确的结果 4.5。它有什么问题?

double average = 0;

Parallel.ForEach(
    Enumerable.Range(0, 10),
    () => 0,
    (elem, loopState, localSum) => {
        localSum += elem;
        return localSum;
    },
    localSum => {
        double localAvg = localSum / 10.0;
        Interlocked.Exchange(ref average, localAvg);
    }
);

Console.WriteLine($"Average in parallel manner: {average}");

例如:

并行平均:0,2

平均并行方式:3,2

并行平均:1,2

但是当我使用类似的代码时一切都很好Interlocked.Add()

int totalSum = 0;

Parallel.For(0, 10, () => 0, (ind, loopState, local) => {
    local += ind;
    return local;
},
local => Interlocked.Add(ref totalSum, local));

Console.WriteLine($"Total sum in parallel manner: {totalSum}");

标签: c#.netparallel-processinginterlocked

解决方案


好吧,如果您将临时本地结果交换为最终结果而不是将它们相加,则会得到错误的结果。函数名称说明了很多。我不确定你为什么期望发生其他事情。

1 + 2 = 3
3 + 4 = 7
5 + 6 = 11
7 + 8 = 15
9 + 10 = 19

现在,如果你把它们全部加起来,你会得到一个正确的结果。如果您以随机顺序全部取走,然后选择最后一个作为您的结果……这在数学上是完全错误的。


推荐阅读