C# 将foreach循环更改为Parallel.foreach和奇怪的bug
我使用传统语法编写了几个循环C# 将foreach循环更改为Parallel.foreach和奇怪的bug,c#,C#,我使用传统语法编写了几个循环 foreach(x in xs) {....} 其中一些循环在计算方面非常密集,我只是使用如下并行语法对其进行了更改: Parallel.ForEach(x, xs => {...}); 我看到性能有了很大的提高!!现在我的问题是:我是否在使用并行多线程引入bug?我读到线程安全是复杂的,会产生奇怪的bug;我应该关心什么?确切地说,发布迭代/循环代码 但总的来说,您的迭代应该彼此独立,并尽量避免共享状态。任何跨并行迭代资源的共享资源都可能引入bug 此外
foreach(x in xs) {....}
其中一些循环在计算方面非常密集,我只是使用如下并行语法对其进行了更改:
Parallel.ForEach(x, xs => {...});
我看到性能有了很大的提高!!现在我的问题是:我是否在使用并行多线程引入bug?我读到线程安全是复杂的,会产生奇怪的bug;我应该关心什么?确切地说,发布迭代/循环代码 但总的来说,您的迭代应该彼此独立,并尽量避免共享状态。任何跨并行迭代资源的共享资源都可能引入bug 此外,当您的计算依赖于其他计算或并行操作或循环时,最好使用TPL任务链,这也有助于避免共享跨线程资源 免费的Microsoft书籍《并行编程模式:理解和应用.NET Framework 4中的并行模式》中详细介绍了更多信息、示例和模式/反模式 在这里下载
访问共享状态很可能不会产生期望的结果。简单的例子:
int sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum++;
}
您将看到sum
将有一些随机值,因为多个线程正在读/写sum
如果您锁定更新,您将解决问题,但实际上您将再次将操作转换为顺序操作
您需要确保循环中发生的任何事情都是安全的
微软的模式和实践证明了这一点。在简单地将代码更改为使用并行循环之前,应该检查一下这一点 如果您只是在不知道代码是否线程安全的情况下更改循环,那么是的,您应该关心!代码将并行运行,因此基本上你不能在并行循环之间共享数据。@BrianRasmussen:你能给我举个例子说明什么是不可以做的吗?你有没有测试这些更改以证明你没有破坏任何东西?你遗漏了最重要的部分
{…}
关于“所有并行工作/不并行工作的事情是什么”的问题对于SO问题来说范围太广了。如果您提供一两个示例,询问它们是否安全将是一个合适的问题。整本书都是关于你所问问题的。
Parallel.For(0, 1000000, i => { sum++; });