【问题标题】:Parallel Programming Interlocked C#并行编程联锁 C#
【发布时间】:2011-11-13 07:51:40
【问题描述】:

我对这个例子感到困惑

http://msdn.microsoft.com/en-us/library/dd997393.aspx

Parallel.ForEach<int, long>(nums, // source collection
                                    () => 0, // method to initialize the local variable
                                    (j, loop, subtotal) => 
                                    {
                                        subtotal += nums[j]; 
                                        return subtotal; 
                                    },

                                    (finalResult) => Interlocked.Add(ref total,finalResult)                                        );

我不知道为什么最后一个代表(finalResult) =&gt; Interlocked.Add(ref total,finalResult) 需要一个 Interlock,而前面的表达式

(j, loop, subtotal) => 
                                    {
                                        subtotal += nums[j]; 
                                        return subtotal; 
                                    },

没有?

谢谢

【问题讨论】:

    标签: c# .net parallel-processing interlocked


    【解决方案1】:

    Parallel.For()Parallel.ForEach() 方法使用了 Partitioner。在 10,000 个单独的任务上执行超过 10,000 个元素的循环是非常低效的。分区器将数据分割成段,理想情况下,ForEach() 将在 4 核 CPU 上的 2,500 个元素的 4 个任务(线程)中执行。这有时需要一些启发式方法,您可以编写自己的自定义分区器。

    当使用ForEach() 的“正常”(简单)重载时,这是完全透明的。但是您的示例使用了显示分区的&lt;TLocal&gt; 重载之一。

    subtotal += nums[j]; 语句在 1 个分区内迭代,因此是线程安全的。

    (finalResult) =&gt; Interlocked.Add(ref total,finalResult)是分区合并的地方,这部分当然不是线程安全的。

    【讨论】:

      【解决方案2】:

      变量subtotal是“本地数据”,只有一个线程可以访问。

      另一方面,total 是一个所有线程都可以修改的变量,并且可能有多个线程可能会尝试同时更新总数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-17
        • 2010-09-20
        • 1970-01-01
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多