并行编程联锁 C#
Posted
技术标签:
【中文标题】并行编程联锁 C#【英文标题】:Parallel Programming Interlocked 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) => Interlocked.Add(ref total,finalResult)
需要一个 Interlock,而前面的表达式
(j, loop, subtotal) =>
subtotal += nums[j];
return subtotal;
,
没有?
谢谢
【问题讨论】:
【参考方案1】:Parallel.For()
和 Parallel.ForEach()
方法使用了 Partitioner。在 10,000 个单独的任务上执行超过 10,000 个元素的循环是非常低效的。分区器将数据分割成段,理想情况下,ForEach()
将在 4 核 CPU 上的 2,500 个元素的 4 个任务(线程)中执行。这有时需要一些启发式方法,您可以编写自己的自定义分区器。
当使用ForEach()
的“正常”(简单)重载时,这是完全透明的。但是您的示例使用了显示分区的<TLocal>
重载之一。
subtotal += nums[j];
语句在 1 个分区内迭代,因此是线程安全的。
而(finalResult) => Interlocked.Add(ref total,finalResult)
是分区合并的地方,这部分当然不是线程安全的。
【讨论】:
【参考方案2】:变量subtotal
是“本地数据”,只有一个线程可以访问。
另一方面,total
是一个所有线程都可以修改的变量,并且可能有多个线程可能会尝试同时更新总数。
【讨论】:
以上是关于并行编程联锁 C#的主要内容,如果未能解决你的问题,请参考以下文章