【发布时间】:2011-08-15 04:20:11
【问题描述】:
我有一个处理大块信息的子程序。为了利用整个 CPU,它将工作分成单独的线程。在所有线程都完成后,它就完成了。我读到创建和销毁线程会占用大量开销,因此我尝试使用线程池,但实际上运行速度比创建自己的线程慢。如何在程序运行时创建自己的线程然后继续重用它们?看到有人说做不到,但是线程池做到了,应该是可以的吧?
这是启动新线程/使用线程池的部分代码:
//initialization for threads
Thread[] AltThread = null;
if (NumThreads > 1)
AltThread = new Thread[pub.NumThreads - 1];
do
{
if (NumThreads > 1)
{ //split the matrix up into NumThreads number of even-sized blocks and execute on separate threads
int ThreadWidth = DataWidth / NumThreads;
if (UseThreadPool) //use threadpool threads
{
for (int i = 0; i < NumThreads - 1; i++)
{
ThreadPool.QueueUserWorkItem(ComputePartialDataOnThread,
new object[] { AltEngine[i], ThreadWidth * (i + 1), ThreadWidth * (i + 2) });
}
//get number of threads available after queue
System.Threading.Thread.Sleep(0);
int StartThreads, empty, EndThreads;
ThreadPool.GetAvailableThreads(out StartThreads, out empty);
ComputePartialData(ThisEngine, 0, ThreadWidth);
//wait for all threads to finish
do
{
ThreadPool.GetAvailableThreads(out EndThreads, out empty);
System.Threading.Thread.Sleep(1);
} while (StartThreads - EndThreads > 0);
}
else //create new threads each time (can we reuse these?)
{
for (int i = 0; i < NumThreads - 1; i++)
{
AltThread[i] = new Thread(ComputePartialDataOnThread);
AltThread[i].Start(new object[] { AltEngine[i], ThreadWidth * (i + 1), ThreadWidth * (i + 2) });
}
ComputePartialData(ThisEngine, 0, ThreadWidth);
//wait for all threads to finish
foreach (Thread t in AltThread)
t.Join(1000);
foreach (Thread t in AltThread)
if (t.IsAlive) t.Abort();
}
}
}
ComputePartialDataOnThread 只是将信息解包并调用 ComputePartialData。将要处理的数据在线程之间共享(它们不会尝试读取/写入相同的位置)。 AltEngine[] 是每个线程的独立计算引擎。
该操作使用线程池运行大约 10-20%。
【问题讨论】:
-
您能否发布您的代码,以便我们了解您在做什么?有可能你的线程池出了问题,导致它变得如此缓慢。
-
也许它只是在您的测试运行中很慢,即您达到了初始线程数,因此它必须创建更多线程以满足您的需求。在运行任何测试之前尝试手动设置池中的最小线程数。
-
线程数与处理器内核数相匹配。在这种情况下,它只有 2 个。
-
请不要使用
Thread.Abort。这是您可以调用的最糟糕的功能。如果您的线程正在做一些关键的事情怎么办?砰,你死了。 -
做到这一点很棘手。但是,使用 ThreadPool 通常是并行化计算绑定操作的最佳方式。我强烈推荐阅读 Jeffrey Richter 的书“通过 C# 进行 CLR”(第五部分“线程”),详细解释如何以及何时使用多线程。
标签: c# .net multithreading threadpool