【问题标题】:Inconsistency in Parallel.ForEach [closed]Parallel.ForEach 中的不一致 [关闭]
【发布时间】:2017-01-16 10:19:10
【问题描述】:

我正在使用 Parallel.foreach 进行超过 500 次迭代。

我的循环是这样的:

Parallel.ForEach(indexes, (index) =>
 {

 //parentCreation with index object
 parent=create(index);

//call of function to create children
createChildrenOfType1(parent);
createChildrenOfType2(parent);
 });

我面临不一致的输出。父母的创建是正确的,但孩子的创建是不一致的。 有时不创建子项,有时只创建少数子项,依此类推。 子创建方法再次具有 for 循环来创建 100 个子。

如何在使用并行 foreach 进行父创建时使我的子创建保持一致。

【问题讨论】:

  • 我认为您将不得不展示您对这些创建方法的实现。
  • 线程不安全的对象是线程不安全的
  • 如果您曾经玩过 GTA 并且玩飞镖喝得太多 - 这就是在多线程环境中使用不安全对象时的世界感觉。这不正常。

标签: c# multithreading foreach parallel-processing task-parallel-library


【解决方案1】:

我在这里看到的一个问题是您正在修改未在 Parallel.ForEach 代码块中声明的变量,在这种情况下您应该锁定它们。

Parallel.ForEach(indexes, (index) =>
 {

 //parentCreation with index object
lock (lockerObject)
{
     parent=create(index);

    //call of function to create children
    createChildrenOfType1(parent);
    createChildrenOfType2(parent);
}
 });

通过使用锁,它可以确保线程正确同步。

【讨论】:

  • 谢谢大家。是的,一些变量是在并行 for 循环之外初始化的,这就是不一致的原因。
  • 我遇到了类似的问题,并且解决了它。不确定这是否是“最好的”方式,但它很容易并且有效。我投了赞成票!
【解决方案2】:

假设您的Parent 对象有一个List<Child> Children 并且您的createChildrenOfTypeX 函数正在向Parent.Children 列表添加一个新子级,并且那些createChildrenOfTypeX 也在运行一组并行代码,那么List 实现必须线程安全;标准 System.Collections.Generic 实现不是线程安全的。

此外,如果您有一个 Parent 的外部集合,您要向其中添加新实例化的父级,这也必须是线程安全的,否则您也可能会丢失您的父级实例。

【讨论】:

    猜你喜欢
    • 2013-09-06
    • 2012-09-28
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多