Comment réutiliser les threads .NET 3.5

J'ai un sous-programme qui traite les gros blocs d'informations. Afin de rendre l'utilisation de l'ensemble de la CPU, il divise le travail dans des threads séparés. Après tous les threads ont terminé, elle se termine. J'ai lu que la création et à la destruction de threads utilise beaucoup de frais généraux, de sorte j'ai essayé d'utiliser le pool de threads, mais qui en fait s'exécute plus lentement que la création de mon propre fils. Comment puis-je créer mon propre fils lorsque le programme s'exécute, puis garder les réutiliser? J'ai vu certaines personnes disent qu'il ne peut pas être fait, mais le pool de threads t-elle donc ça doit être possible, non?

Voici la partie du code qui lance de nouveaux threads /utilise le pool de threads:

//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 simplement unpackages les informations et les appels ComputePartialData. Les données qui seront traitées est partagé entre les threads (ils n'essayez pas de lire/écrire les mêmes endroits). AltEngine[] est un calcul séparé du moteur pour chaque thread.

L'opération s'exécute environ 10 à 20% en utilisant le pool de threads.

  • Pourriez-vous poster votre code afin que nous puissions voir ce que vous faites? Il est possible que vous êtes en train de faire quelque chose de mal avec le pool de threads qui est à l'origine pour être si lent.
  • C'est peut-être lent que dans votre essai, c'est à dire que vous frappez le thread initial comte, donc il a de créer plusieurs threads pour répondre à vos besoins. Essayez de régler manuellement minimum nombre de threads dans la piscine avant de lancer les tests.
  • Le nombre de threads est destiné à correspondre au nombre de cœurs de processeur. Dans ce cas, c'est seulement 2.
  • Veuillez vous débarrasser de votre utilisation de Thread.Abort. Il s'agit de la pire des fonction, vous pouvez l'appeler. Que faire si votre fils était en train de faire quelque chose de critique? D'un coup, vous êtes mort.
  • L'obtention de ce droit est délicate. Cependant, l'utilisation du pool de threads est généralement va être la meilleure façon de parallelising de calcul lié opérations. Je recommande absolument la lecture de Jeffrey Richter livre "CLR via C#" (partie V "Threading") pour une explication détaillée de comment et quand le multi-thread.
  • Vous interrompez le fils dans l'autre cas. Serait-il possible que ComputePartialData(ThisEngine, 0, ThreadWidth) est très rapide, ce qui sera la cause de votre thread principal pour abandonner ses threads de travail prématurément. Qu'advient-il si vous utilisez t.Join() à la place? Comment beaucoup plus lent sera le cas d'autre alors?

InformationsquelleAutor HypnoToad | 2011-04-29