首页 > 解决方案 > Parallel-For 循环和一致性

问题描述

我正在处理带有外部和内部循环的欧拉问题。外部循环包含被检查的值,内部循环控制通过多少次测试迭代,在这种情况下寻找 Lychrel 数。

外循环并行工作得很好,但内循环非常不一致。你可以从我注释掉的行中看到我已经尝试过 aList<T>和 used locking,以及 using ConcurrentQueue<T>. 我最初的实现使用了一个设置为 true 的 bool(该数字是一个 Lychrel 数),如果在 n 次迭代后证明不是这样,它将被设置为 false。然后它只会计算收集到的 Lychrel 数字的数量。bool 操作效果不佳,跳出内循环(即使有lock)。我什至尝试实现一个线程安全的布尔值,但到目前为止,没有什么能保持内部循环的一致性。在这一点上,它已成为一种学习练习。我通常对线程很熟悉,即使在集合中也经常使用它,但这让我很难理解问题的根本原因。

static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        BigInteger answer = 0;
        List<long> lychrels = new List<long>();
        ConcurrentQueue<long> CQlychrels = new ConcurrentQueue<long>();
        long maxValue = 10000;
        long maxIterations = 50;


        sw.Start();
        //for (int i = 1; i < maxValue; i++)
        Parallel.For(1, maxValue, i =>
        {
            BigInteger workingValue = i;
            //bool lychrel = true;

            //for (int w = 1; w < maxIterations; w++)
            Parallel.For(1, maxIterations, (w, loopstate) =>
            {
                workingValue = workingValue.LychrelAdd();
                if (workingValue.ToString().Length > 1)
                    if (IsPalindrome(workingValue))
                    {
                        //lychrel = false;
                        CQlychrels.Enqueue(i);
                        //lock (lychrels)
                            //lychrels.Add(i);
                        loopstate.Break();

                        //break;
                    }
            });

            //if (!lychrel)
                //lock (lychrels)
                    //lychrels.Add(i);
        });

        answer = maxValue - CQlychrels.Count();

        sw.Stop();

        Console.WriteLine("Answer: " + answer);
        Console.WriteLine("Found in " + sw.ElapsedTicks + " ticks.");
        Console.WriteLine("Found in " + sw.ElapsedMilliseconds + "ms.");

        while (Console.ReadKey() == null)
        { }

        Environment.Exit(0);
    }

BigInteger.LychrelAdd()只需获取价值和价值的镜像,然后将它们加在一起。

我怀疑,也许,要么是线程安全的,要么IsPalindrome()不是线程安全的可能是原因?在那个循环之外设置workingValue并在里面处理它?与BigInteger作为参考值和参考变化有关吗?

标签: c#parallel-processingpass-by-reference

解决方案


推荐阅读