2010-07-07 7 views
3

Existe-t-il un moyen de créer des «threads de travail»? Essentiellement, j'ai essayé de créer des threads chaque fois que j'en avais besoin et cela a été plus lent qu'avec 1 thread. Serait-il possible de créer des threads de travail au démarrage de l'application, puis de leur donner du travail si nécessaire?Créer des fils de travail?

Merci

+0

quelle plateforme? comment créez-vous des discussions? – Naveen

+1

Utilisez-vous C ou C++? Ils ne sont pas la même langue. –

Répondre

7

Oui, vous pouvez créer les threads à l'avant et les faire attendre que les signaux aillent et commencent leur travail.

Ces signaux peuvent être des files d'attente de messages ou des sémaphores ou tout autre type de méthode de communication entre threads.

À titre d'exemple, nous avons déjà assemblé un système sous UNIX qui avait un thread maître pour recevoir du travail sur le réseau et exporter les jobs vers des threads esclaves. Les threads esclaves doivent en réalité interagir avec un autre système par grattage d'écran (émulant essentiellement un utilisateur) pour obtenir l'information désirée. En d'autres termes, le travail pourrait arriver plus vite que les threads esclaves pourraient le faire.

Nous avons donc démarré une cinquantaine d'esclaves impairs et créé juste une variable de condition pour eux (en utilisant pthreads). Chaque esclave qui ne faisait pas de travail actif a simplement attendu la variable de condition. Quand un travail arrivait sur le thread principal, il chargeait les données pertinentes dans la mémoire connue et "envoyait" la variable de condition, réveillant l'un des esclaves qui saisissait alors le travail et commençait à le traiter (après avoir notifié le maître qu'il pourrait continuer).

Il n'y avait donc pas de frais généraux à devoir créer des threads à la volée - tous étaient créés au démarrage de l'application et attendaient simplement que le travail soit transféré.

Bien sûr, il existe un inconvénient potentiel à ce type de dimensionnement statique: vous risquez de rencontrer des problèmes si vous avez réellement besoin de plus de threads. Nous l'avons résolu en surveillant simplement le nombre maximum de threads et en nous assurant que le processus était redémarré le jour suivant avec plus de points si nous étions constamment à court d'argent.


Si vous voulez avoir une solution plus dynamique, vous avez besoin de se pencher sur un concept appelé la mise en commun de fil. C'est essentiellement ce que j'ai décrit ci-dessus mais cela vous permet généralement de définir un nombre minimum et maximum de threads avec un temps maximum qu'un thread inactif sera autorisé à survivre sans travail (sauf si vous êtes déjà au minimum).

Sa mise en œuvre pourrait être quelque chose d'aussi simple que:

master: 
    minslaves = 7 
    maxslaves = 20 
    maxtime = 600 
    numslaves = 0 
    freeslaves = 0 

    while running: 
     while numslaves < minslaves: 
      increment numslaves and freeslaves 
      start a slave 
     endwhile 
     wait for work 
     if freeslaves = 0 and numslaves < maxslaves: 
      start a slave 
     endif 
     queue work to slavequeue 
    endwhile 
    while numslaves > 0: 
     wait 
    endwhile 
    exit 

et:

slave: 
    while running: 
     get work from slavequeue with timeout 
     if timed out: 
      if time since last work > maxtime and numslaves > minslaves: 
       break out of while loop 
      endif 
      restart while loop 
     endif 
     decrement freeslaves 
     do the work 
     increment freeslaves 
    endwhile 
    decrement numslaves and freeslaves 
    exit 

(avec protection sémaphores appropriée de toutes les variables partagées bien sûr, numslaves, freeslaves, slavequeue et les autres si vous décidez de les changer après le démarrage des threads). Et, si votre environnement a déjà un pool de threads, je vous suggère de l'utiliser plutôt que d'essayer de convertir mon pseudo-code ci-dessus.Mon code est de la mémoire et est destiné à illustrer un point - il peut ou non être sans bug :-)

0

Ceci est généralement effectué en créant des files d'attente de messages. Un thread attendrait sur un objet, signalant lequel indiquera qu'il y a du nouveau travail à accomplir.

+0

aussi: les threads ne sont pas un moyen d'améliorer les performances, à moins que vous ne fassiez quelque chose de très computationnel et lié par le CPU. Les threads –

+0

peuvent également améliorer les performances des applications liées aux E/S, tant que vous lisez (par exemple) un périphérique et écrivez dans un autre. –

+0

@Jerry, séparer la lecture et l'écriture n'est pas le point crucial des applications liées aux E/S, en utilisant différents périphériques par thread. –

0

Sur win32 il y a un très bon pool de threads - esp Vista et Windows 7 et suivantes. J'ai toujours trouvé utile de penser en termes de tâches qui doivent être effectuées simultanément que de penser à des threads individuels.

En outre, la bibliothèque de modèles parallèles (ConcRT je pense que cela s'appelle) qui vient avec Visual C++ 2010 semble très puissante (et possède une interface simple). Je ne l'ai pas encore utilisé moi-même cependant. Le lien MSDN est - http://msdn.microsoft.com/en-us/library/dd492418.aspx