Quelle est la bonne façon d’utiliser un ThreadPool?

Si ma compréhension du fonctionnement de ThreadPool est correcte, l’un de ses objectives est de limiter le nombre de threads de travail dans un processus pouvant être créés à un moment donné. Par exemple, si vous définissez MaxThreads sur 5, puis appelez QueueUserWorkItem 30 fois, 30 requêtes seront envoyées au ThreadPool, mais seules 5 de ces demandes seront traitées par un nouveau thread, tandis que les 25 autres seront ajoutées à la queue. et traité un à un à mesure que les demandes précédentes sont terminées et que les threads existants deviennent disponibles.

Cependant, dans le code ci-dessous, l’appel de Thread.Sleep (-1) garantit que la méthode DoSomething () ne sera jamais renvoyée, ce qui signifie que le thread actuel ne sera jamais disponible pour les requêtes suivantes.

Mais ma compréhension du fonctionnement d’un ThreadPool ne peut pas être correcte, car si c’était le cas, le code ci-dessous n’indiquerait que les chiffres 0-4, plutôt que 0-29.

Quelqu’un peut-il s’il vous plaît expliquer comment fonctionne le ThreadPool et pourquoi le code ci-dessous ne fait pas ce que je pensais qu’il devrait faire?

static void DoSomething(object n) { Console.WriteLine(n); Thread.Sleep(-1); } static void Main(ssortingng[] args) { ThreadPool.SetMaxThreads(5, 5); for (int x = 0; x < 30; x++) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x); } Console.Read(); } 

ThreadPool.SetMaxThreads(5, 5)

signifie que le nombre de threads actifs est 5 (si vous avez plus de 5 cpu), cela ne signifie pas que le ThreadPool ne peut créer que 5 threads. Le nombre maximal de threads ThreadPool = CPU Core * 250.

Après Thread.Sleep , le thread est inactif, cela n’affectera donc pas l’exécution des autres threads.

Mais ma compréhension du fonctionnement d’un ThreadPool ne peut pas être correcte, car si c’était le cas, le code ci-dessous n’indiquerait que les chiffres 0-4, plutôt que 0-29.

Oui, votre hypothèse est tout à fait correcte.

Etant donné que vous avez mis en queue 30 tâches dans un ThreadPool et que les tâches seront suspendues pour InfiniteTime, elles ne se termineront jamais. La classe ThreadPool attendra un certain intervalle pour créer un nouveau thread, sans toutefois dépasser le nombre maximal de threads.

REMARQUE

Console.Read () maintient votre thread d’arrière-plan en vie.

Des articles

  • Comment utiliser un ThreadPool
  • Travailler avec ThreadPool

À partir de MSDN

De nombreuses applications créent des threads qui passent beaucoup de temps dans l’état de veille en attente d’un événement. D’autres threads peuvent entrer dans un état de veille uniquement pour être réveillés périodiquement afin de rechercher une information de changement ou de mise à jour. Le regroupement de threads vous permet d’utiliser les threads plus efficacement en fournissant à votre application un pool de threads de travail gérés par le système. Un thread surveille le statut de plusieurs opérations d’attente mises en queue dans le pool de threads. Lorsqu’une opération d’attente est terminée, un thread de travail du pool de threads exécute la fonction de rappel correspondante.


Lorsque tous les threads du pool de threads ont été affectés à des tâches, le pool de threads ne commence pas immédiatement à créer de nouveaux threads inactifs. Pour éviter d’allouer inutilement de l’espace de stack aux threads, il crée de nouveaux threads inactifs à intervalles réguliers. L’intervalle est actuellement d’une demi-seconde, bien qu’il puisse changer dans les futures versions du .NET Framework.


Les threads du pool de threads gérés sont des threads d’arrière-plan. C’est-à-dire que leurs propriétés IsBackground sont vraies. Cela signifie qu’un thread ThreadPool ne continuera pas l’exécution d’une application après la fin de tous les threads d’avant-plan.

Il se peut que Thread.Sleep (-1) ne fasse pas ce que vous attendez.

Paramètre Int32: Le nombre de millisecondes pour lequel le thread est bloqué. Spécifiez zéro (0) pour indiquer que ce thread doit être suspendu pour permettre à d’autres threads en attente de s’exécuter. Spécifiez Infinite pour bloquer le thread indéfiniment.

http://msdn.microsoft.com/en-us/library/d00bd51t.aspx

Vous devriez regarder dans Tasks, http://msdn.microsoft.com/en-us/library/dd235608.aspx Pensez-y comme à Threadpool 2.0

En règle générale, ThreadPool crée un nombre de threads égal au nombre de cœurs de la CPU. Il n’est pas nécessaire de créer plus de threads, un seul thread pouvant être traité par le kernel à la fois. Mais, lorsque la tâche mise en queue dans un ThreadPool nécessite plus de 0,5 seconde pour s’exécuter, le ThreadPool crée un thread supplémentaire pour gérer les tâches restantes dans une queue. Donc, si vous mettez beaucoup de tâches lourdes en queue dans un ThreadPool, cela créera beaucoup de threads supplémentaires pour émuler le multitâche et exécuter toutes les tâches en «parallèle». Mais le temps d’exécution total serait le même que s’il n’y avait pas de threads supplémentaires. De plus, il le serait encore moins parce que la création du thread est une opération assez lourde. C’est pourquoi ThreadPool est recommandé pour les petites tâches afin d’éviter la création de threads supplémentaires qui ne présentent aucun avantage.

Vous pouvez en savoir plus sur ThreadPool dans l’ article d’Albahari . En fait, il y a de nombreux articles sur le filetage.