c# - Parallel-For 循环和一致性
问题描述
我正在处理带有外部和内部循环的欧拉问题。外部循环包含被检查的值,内部循环控制通过多少次测试迭代,在这种情况下寻找 Lychrel 数。
外循环并行工作得很好,但内循环非常不一致。你可以从我注释掉的行中看到我已经尝试过 aList<T>
和 used lock
ing,以及 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
作为参考值和参考变化有关吗?