Question

Quand dois-je pas utiliser le ThreadPool dans .Net ?

Il semble que la meilleure option soit d’utiliser un ThreadPool, auquel cas, pourquoi n’est-ce pas la seule option ?

Quelles sont vos expériences à ce sujet ?

Était-ce utile?

La solution

La seule raison pour laquelle je n'utiliserais pas le ThreadPool pour le multithreading bon marché, c'est si j'en ai besoin…

  1. interagir avec la méthode en cours d'exécution (par exemple, pour la tuer)
  2. exécuter du code sur un Fil de discussion STA (ça m'est arrivé)
  3. garder le fil de discussion en vie après la mort de ma candidature (ThreadPool les fils de discussion sont des fils de discussion d'arrière-plan)
  4. au cas où je devrais changer la priorité du fil.Nous ne pouvons pas modifier la priorité des threads dans ThreadPool qui est par défaut Normal.

P.S. : L'article MSDN "Le pool de threads gérés" contient une section intitulée, "Quand ne pas utiliser les threads du pool de threads", avec une liste très similaire mais légèrement plus complète de raisons possibles pour ne pas utiliser le pool de threads.

Il existe de nombreuses raisons pour lesquelles vous devrez ignorer le ThreadPool, mais si vous ne les connaissez pas, alors le ThreadPool devrait être assez bien pour vous.

Sinon, regardez le nouveau Cadre d'extensions parallèles, qui contient des éléments intéressants qui peuvent répondre à vos besoins sans avoir à utiliser le ThreadPool.

Autres conseils

@Eric, je vais devoir être d'accord avec Dean.Les fils sont chers.Vous ne pouvez pas supposer que votre programme est le seul à fonctionner.Quand tout le monde est avide de ressources, le problème se multiplie.

Je préfère créer mes fils de discussion manuellement et les contrôler moi-même.Cela rend le code très facile à comprendre.

C'est bien quand c'est approprié.Si vous avez besoin de plusieurs threads de travail, tout ce que vous avez fait est de compliquer votre code.Il faut maintenant écrire du code pour les gérer.Si vous utilisiez simplement un pool de threads, vous obtiendriez toute la gestion des threads gratuitement.Et le pool de threads fourni par le langage est très probablement plus robuste, plus efficace et moins bogué que tout ce que vous lancez vous-même.

Thread t = new Thread(new ThreadStart(DoSomething));  
t.Start();  
t.Join();  

J'espère que vous auriez normalement du code supplémentaire entre les deux Start() et Join().Sinon, le fil supplémentaire est inutile et vous gaspillez des ressources sans raison.

Les gens ont bien trop peur des ressources utilisées par les threads.Je n'ai jamais vu la création et le démarrage d'un fil de discussion prendre plus d'une milliseconde.Il n’y a pas de limite stricte quant au nombre de threads que vous pouvez créer.L'utilisation de la RAM est minime.Une fois que vous disposez de quelques centaines de threads, le processeur devient un problème en raison des changements de contexte. À ce stade, vous souhaiterez peut-être améliorer votre conception.

Une milliseconde est une long temps sur du matériel moderne.Cela représente 3 millions de cycles sur une machine à 3 GHz.Et encore une fois, vous n'êtes pas le seul à créer des discussions.Vos threads sont en compétition pour le processeur avec les threads de tous les autres programmes.Si vous n'utilisez pas trop de threads, et qu'un autre programme aussi, alors ensemble, vous avez utilisé trop de threads.

Sérieusement, ne rendez pas la vie plus complexe qu’elle ne devrait l’être.N'utilisez pas le pool de threads, sauf si vous avez besoin de quelque chose de très spécifique qu'il propose.

En effet.Ne compliquez pas la vie.Si votre programme a besoin de plusieurs threads de travail, ne réinventez pas la roue.Utilisez le pool de threads.C'est pourquoi il est là.Souhaitez-vous lancer votre propre classe de cordes ?

Les pools de threads ont du sens chaque fois que vous avez le concept de threads de travail.Chaque fois que vous pouvez facilement partitionner le traitement en tâches plus petites, chacune pouvant être traitée indépendamment, les threads de travail (et donc un pool de threads) ont du sens.

Les pools de threads n'ont pas de sens lorsque vous avez besoin de threads qui effectuent des actions totalement différentes et sans rapport, qui ne peuvent pas être considérées comme des « tâches » ;par exemple, un thread pour la gestion des événements GUI, un autre pour le traitement backend.Les pools de threads n'ont pas non plus de sens lorsque le traitement forme un pipeline.

Fondamentalement, si vous avez des threads qui démarrent, traitent une tâche et se terminent, un pool de threads est probablement la solution.Sinon, le pool de threads ne sera pas vraiment utile.

À la réponse querelleuse, j'ajouterais qu'il est préférable de ne pas utiliser de thread ThreadPool si vous devez garantir que votre thread commencera à fonctionner immédiatement.Le nombre maximum de threads regroupés en cours d'exécution est limité par domaine d'application, de sorte que votre travail devra peut-être attendre s'ils sont tous occupés.Après tout, cela s'appelle « élément de travail de l'utilisateur de la file d'attente ».

Deux mises en garde, bien sûr :

  1. Vous pouvez modifier le nombre maximum de threads regroupés dans le code, au moment de l'exécution, donc rien ne vous empêche de vérifier le nombre actuel par rapport au nombre maximum et d'augmenter le maximum si nécessaire.
  2. La création d'un nouveau fil de discussion entraîne sa propre pénalité de temps - la question de savoir si cela vaut la peine pour vous de prendre le coup dépend de votre situation.

Je ne parle pas comme quelqu'un avec seulement des connaissances théoriques ici.J'écris et maintient des applications à volume élevé qui utilisent fortement le multithreading, et je ne trouve généralement pas que le pool de threads est la bonne réponse.

Ah, argument d'autorité - mais soyez toujours à l'affût des personnes susceptibles de faire partie de l'équipe du noyau Windows.

Aucun de nous ne contestait le fait que si vous avez des exigences spécifiques, le .NET ThreadPool n'est peut-être pas la bonne chose.Ce à quoi nous nous opposons, c'est la banalisation des coûts supportés par la machine pour créer un fil.

La dépense importante liée à la création d'un fil de discussion est la raison d'être du ThreadPool en premier lieu.Je ne veux pas que mes machines soient remplies de code écrit par des personnes qui ont été mal informées sur les dépenses liées à la création d'un thread et qui ne savent pas, par exemple, que cela provoque l'appel d'une méthode dans chaque DLL qui est attaché au processus (dont certains seront créés par des tiers), et qui pourrait très bien faire chauffer une charge de code qui n'a pas besoin du tout d'être dans la RAM et n'a presque certainement pas besoin d'être en L1.

La forme de la hiérarchie de la mémoire dans une machine moderne signifie que « distraire » un processeur est la pire chose que vous puissiez faire, et tous ceux qui se soucient de leur métier devraient travailler dur pour l'éviter.

Lorsque vous allez effectuer une opération qui va prendre beaucoup de temps, ou peut-être un fil d'arrière-plan continu.Je suppose que vous pouvez toujours augmenter le nombre de threads disponibles dans le pool, mais cela ne servirait à rien d'engager les coûts de gestion d'un thread qui ne sera jamais restitué au pool.

MSDN a une liste de quelques raisons ici :

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

Il existe plusieurs scénarios dans lesquels il est approprié de créer et de gérer vos propres threads au lieu d'utiliser des threads de pool de threads:

  • Vous avez besoin d'un fil de premier plan.
  • Vous avez besoin qu’un thread ait une priorité particulière.
  • Vous avez des tâches qui provoquent le blocage du thread pendant de longues périodes.Le pool de threads a un nombre maximum de threads, donc un grand nombre de threads de pool de filetages bloqués pourraient empêcher les tâches de démarrer.
  • Vous devez placer les threads dans un appartement à un seul thread.Tous les threads ThreadPool se trouvent dans le cloisonnement multithread.
  • Vous devez avoir une identité stable associée au thread ou dédier un thread à une tâche.

Les threads Threadpool conviennent aux tâches qui répondent aux deux critères suivants :

  1. La tâche ne nécessitera pas beaucoup de temps à attendre que quelque chose se produise
  2. Tout ce qui attend la fin de la tâche attendra probablement la fin de nombreuses tâches, donc sa priorité de planification n'est pas susceptible d'affecter beaucoup les choses.

Utiliser un thread de pool de threads au lieu d'en créer un nouveau permettra de gagner un temps important mais limité.Si ce temps est important par rapport au temps nécessaire pour effectuer une tâche, une tâche de pool de threads est probablement appropriée.Toutefois, plus le temps requis pour effectuer une tâche est long, plus l'avantage de l'utilisation du pool de threads est faible et plus la probabilité que la tâche entrave l'efficacité du pool de threads est grande.

@Éric

@Derek, je ne suis pas tout à fait d'accord avec le scénario que vous utilisez comme exemple.Si vous ne savez pas exactement ce qui s'exécute sur votre machine et combien de threads, de handles, de temps CPU, de RAM, etc., que votre application utilisera sous une certaine charge, vous avez des problèmes.

Êtes-vous le seul client cible des programmes que vous écrivez ?Sinon, vous ne pouvez pas en être certain pour la plupart.Lorsque vous écrivez un programme, vous ne savez généralement pas s'il s'exécutera efficacement en solo ou s'il s'exécutera sur un serveur Web martelé par une attaque DDOS.Vous ne pouvez pas savoir de combien de temps CPU vous disposerez.

En supposant que le comportement de votre programme change en fonction des entrées, il est rare de savoir exactement combien de mémoire ou de temps CPU votre programme consommera.Bien sûr, vous devriez avoir une assez bonne idée de la façon dont votre programme va se comporter, mais la plupart des programmes ne sont jamais analysés pour déterminer exactement la quantité de mémoire, le nombre de handles, etc.sera utilisée, car une analyse complète coûte cher.Si vous n'écrivez pas de logiciel en temps réel, le gain n'en vaut pas la peine.

En général, prétendre savoir exactement comment votre programme se comportera est tiré par les cheveux, et prétendre tout savoir sur la machine est ridicule.

Et pour être honnête, si vous ne savez pas exactement quelle méthode utiliser :threads manuels, pool de threads, délégués et comment l'implémenter pour faire exactement ce dont votre application a besoin, vous avez des problèmes.

Je ne suis pas totalement en désaccord, mais je ne vois pas vraiment en quoi cela est pertinent.Ce site est là spécifiquement parce que les programmeurs n'ont pas toujours toutes les réponses.

Si votre application est suffisamment complexe pour nécessiter une limitation du nombre de threads que vous utilisez, ne souhaiterez-vous pas presque toujours plus de contrôle que ce que le framework vous donne ?

Non.Si j'ai besoin d'un pool de threads, j'utiliserai celui fourni, à moins et jusqu'à ce que je trouve qu'il n'est pas suffisant.Je ne supposerai pas simplement que le pool de threads fourni est insuffisant pour mes besoins sans confirmer que c'est le cas.

Je ne parle pas ici en tant que personne ayant uniquement des connaissances théoriques.J'écris et maintiens des applications à volume élevé qui font un usage intensif du multithreading, et je ne trouve généralement pas que le pool de threads soit la bonne réponse.

La plupart de mon expérience professionnelle a porté sur des programmes multithreading et multitraitement.J'ai souvent eu besoin de lancer ma propre solution également.Cela ne veut pas dire que le pool de threads n’est pas utile ou approprié dans de nombreux cas.Le pool de threads est conçu pour gérer les threads de travail.Dans les cas où plusieurs threads de travail sont appropriés, le pool de threads fourni doit généralement être la première approche.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top