【发布时间】:2015-03-19 09:36:45
【问题描述】:
我正在尝试创建一个并行计算数字阶乘的函数,仅用于测试目的。 假设我的 cpu 上有 4 个核心,所以我会将“问题”分成 4 个块。
这么说,我做了这个:
public class FactorialPTest
{
public static object _locker = new object();
public static long Factorial(int x)
{
long result = 1;
int right = 0;
int nr = x;
bool done = false;
for (int i = 0; i < nr; i += (nr / 4))
{
int step = i;
new Thread(new ThreadStart(() =>
{
right = (step + nr / 4) > nr ? nr : (step + nr / 4);
long chunkResult = ChunkFactorial(step + 1, right);
lock (_locker)
{
result *= chunkResult;
if (right == nr)
done = true;
}
})).Start();
}
while(!done)
{
Thread.Sleep(10);
}
return result;
}
public static long ChunkFactorial(int left, int right)
{
//Console.WriteLine("left: {0} ; right: {1}", left, right);
Console.WriteLine("ChunkFactorial Thread ID :" + Thread.CurrentThread.ManagedThreadId);
if (left == right)
return left == 0 ? 1 : left;
else return right * ChunkFactorial(left, right - 1);
}
public static void main()
{
Console.WriteLine(Factorial(15));
}
}
有时有效,有时它会给我中间结果,有时会发生死锁。
为什么会这样? Thread.Sleep(10) 不应该暂停主线程直到我得到最终结果吗?
【问题讨论】:
-
对于初学者来说,如果一个线程在其他线程完成之前将 done 设置为 true 怎么办?
-
尝试适当的线程同步,例如一个信号量并等待所有线程结束。
-
@RagtimeWilly 这就是为什么我把那个部分放在一个锁块中,这样一个线程一次可以使部分结果相乘。只有最后一个应该设置为 true (通过检查正确是否等于正在计算的阶乘。
-
@darkdante - 但“最后一个”可以在其他一个之前完成。
-
@Damien_The_Unbeliever 谢谢,我错过了:)
标签: c# .net multithreading parallel-processing factorial