У меня есть подпрограмма, которая обрабатывает большие блоки информации. Чтобы использовать весь процессор, он разделяет работу на отдельные потоки. После того, как все потоки завершены, он заканчивается. Я читал, что создание и удаление потоков требует много накладных расходов, поэтому я попытался использовать пул потоков, но на самом деле он работает медленнее, чем создание собственных потоков. Как я могу создавать свои собственные потоки, когда программа запускается, а затем снова использовать их? Я видел, как некоторые люди говорят, что это не может быть сделано, но пул потоков делает это так, это должно быть возможно, верно?
Вот часть кода, который запускает новые потоки / использует пул потоков:
//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% с использованием пула потоков.