并行循环时丢失值

本文关键字:循环 并行 | 更新日期: 2023-09-27 18:20:08

我面临着一个无法解释的奇怪问题,我想知道你们中的一些人是否知道我所缺乏的答案。

我有一个小的测试应用程序,用于测试我对更大代码所做的多线程修改。在这个应用程序中,我设置了两个函数,一个按顺序执行循环,另一个使用Task.Parallel.For。这两个函数打印出生成的时间和最终元素。我看到的是,执行Parallel.For的函数生成的项目比顺序循环少,这对真正的应用程序来说是一个巨大的问题(它扰乱了一些最终结果)。所以,我的问题是,是否有人知道为什么会发生这种情况,如果是的话,是否有办法解决它

以下是在我的测试应用程序中使用parallel.fo的函数的代码:

static bool[] values = new bool[52];
static List<int[]> combinations = new List<int[]>();
static void ParallelLoop()
{
    combinations.Clear();
    Parallel.For(0, 48, i =>
    {
        if (values[i])
        {
            for (int j = i + 1; j < 49; j++)
                if (values[j])
                {
                    for (int k = j + 1; k < 50; k++)
                    {
                        if (values[k])
                        {
                            for (int l = k + 1; l < 51; l++)
                            {
                                if (values[l])
                                {
                                    for (int m = l + 1; m < 52; m++)
                                    {
                                        if (values[m])
                                        {
                                            int[] combination = { i, j, k, l, m };
                                            combinations.Add(combination);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        }
    }); // Parallel.For
}

这是应用程序的输出:

Executing sequential loop...
Number of elements generated: 1,712,304
Executing parallel loop...
Number of elements generated: 1,464,871

提前谢谢,如果你需要澄清,我会尽我所能进一步详细解释。

并行循环时丢失值

在没有任何同步机制的情况下,不能通过多个线程同时在列表中添加项目。List<T>.Add()实际上做一些非琐碎的内部事务(缓冲区等),因此添加一个项是而不是原子线程安全操作。

任一:

  • 提供一种同步写入的方法
  • 使用支持并发写入的集合(请参见System.Collections.Concurrent命名空间)
  • 根本不使用多线程