首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >将foreach循环更改为Parallel.ForEach和奇怪的错误

将foreach循环更改为Parallel.ForEach和奇怪的错误
EN

Stack Overflow用户
提问于 2012-07-24 00:45:46
回答 2查看 849关注 0票数 4

我有几个使用传统语法编写的循环

代码语言:javascript
代码运行次数:0
运行
复制
foreach(x in xs) {....}

其中一些循环在计算方面相当密集,我只是使用如下的并行语法对它们进行了更改:

代码语言:javascript
代码运行次数:0
运行
复制
Parallel.ForEach(x, xs => {...});

我看到性能有了很大的提高!现在我的问题是:我是否引入了使用并行多线程的bug?我读到线程安全是复杂的,可能会产生奇怪的bug;我应该关注什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-24 00:57:09

访问共享状态很可能不会产生期望的结果。简单的例子:

代码语言:javascript
代码运行次数:0
运行
复制
int sum = 0;
for (int i = 0; i < 1000000; i++)
{
    sum++;
}

将其更改为

代码语言:javascript
代码运行次数:0
运行
复制
Parallel.For(0, 1000000, i => { sum++; });

你会看到sum会有一些随机值,因为多线程正在读/写sum

如果锁定更新,就可以解决问题,但本质上会再次将操作转换为顺序操作。

您需要确保循环中发生的任何事情都是安全的。

微软的模式和实践做了a book,解释了这一切甚至更多。在简单地将代码更改为使用并行循环之前,您应该先检查一下。

票数 4
EN

Stack Overflow用户

发布于 2012-07-24 00:51:56

确切地说--发布你的迭代/循环代码。

但总的来说,您的迭代应该彼此独立,并尽量避免共享状态。任何与并行迭代资源交叉的共享资源都可能引入bug。

此外,当您的计算依赖于一些其他计算或并行操作或循环时,最好使用TPL任务链,这也有助于避免共享跨线程资源。

更多信息、示例和模式/反模式在微软的免费书籍《并行编程的模式:使用.NET框架理解和应用并行模式4》中有很好的描述

请在此处下载

http://www.microsoft.com/en-us/download/details.aspx?id=19222

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11616833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档