gpt4 book ai didi

list - 并行For循环-添加到列表时出现问题

转载 作者:行者123 更新时间:2023-12-04 13:12:26 25 4
gpt4 key购买 nike

我遇到一些涉及Parallel for循环并添加到列表的问题。问题是,相同的代码可能在不同的时间生成不同的输出。我在下面设置了一些测试代码。在此代码中,我创建了一个10,000个int值的列表。值的1/10将为0,值的1/10将为1,一直到值的1/10为止为9。

设置完此列表后,我设置了一个用于循环访问列表的Parallel for循环。如果当前数字为0,则向新列表中添加一个值。在Parallel for循环完成后,我输出列表的大小。大小应始终为1,000。大多数时候,给出正确的答案。但是,我已经看到3种可能出现的不正确结果:

  • 列表的大小小于1,000
  • 发生IndexOutOfRangeException @ doubleList.Add(0.0);
  • 发生ArgumentException @ doubleList.Add(0.0);

  • 给定的ArgumentException消息为: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
    是什么导致错误?这是.Net错误吗?我有什么办法可以防止这种情况的发生?

    请自己尝试代码。如果没有出现错误,请尝试几次。另请注意,使用单核计算机可能不会看到任何错误。
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    namespace ParallelTest
    {
    class Program
    {
    static void Main(string[] args)
    {
    List<int> intList = new List<int>();
    List<double> doubleList = new List<double>();

    for (int i = 0; i < 250; i++)
    {
    intList.Clear();
    doubleList.Clear();

    for (int j = 0; j < 10000; j++)
    {
    intList.Add(j % 10);
    }

    Parallel.For(0, intList.Count, j =>
    {
    if (intList[j] == 0)
    {
    doubleList.Add(0.0);
    }
    });

    if (doubleList.Count != 1000)
    {
    Console.WriteLine("On iteration " + i + ": List size = " + doubleList.Count);
    }
    }

    Console.WriteLine("\nPress any key to exit.");
    Console.ReadKey();
    }
    }
    }

    最佳答案

    我希望System.Collections.Generic.List不是线程安全的,这意味着如果您尝试同时从两个不同的线程中Add,事情将会出错。是的,它在docs中是这样说的。

    您可以通过多种方式阻止这种情况的发生:

  • 使用允许线程安全添加的集合类型(.Net 4.0中有一些new ones)
  • 在添加之前先锁定
  • 对集合使用线程本地存储,并在末尾合并它们
  • ...

  • 这些是数据并行代码遇到的非常典型的问题。

    关于list - 并行For循环-添加到列表时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2752358/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com