2011-03-30 2 views
1

Je souhaite créer un pool de threads simple (sur un système * nix) pour gérer les entrées sur mon serveur de communication asynchrone. Et j'ai quelques questions. Au début, je veux juste avoir un nombre statique de threads, disons arbitrairement 6.Mise en œuvre du pool de threads

Comment dois-je envoyer la commande au thread de travail?

Je pensais à l'aide de communication simple socket, avec quelque chose comme ça

thread principal :: envoyer [socket (RECV) (envoyer) otherSocket];

puis avoir mes threads simplement bloquer sur l'appel de réception, est-ce horriblement inefficace?

Y a-t-il une bibliothèque que je devrais utiliser? Y a-t-il de meilleures méthodes d'implémentation

(plus tard, je vais faire les fils dynamiques, je viens de comprendre qu'il serait plus facile de commencer par un numéro de série)

Répondre

3

Tout d'abord, vous devez réaliser que Windows n'a pas seulement un, mais deux Intégration d'API de pool de threads Au cas où cela ne suffisait pas, les ports de complétion d'E/S sont également essentiellement des pools de threads déguisés. En tant que tel, il ya probablement pas beaucoup de raison d'écrire votre propre pool de threads du tout. À moins que vous ne prévoyiez d'autoriser l'exécution de vos threads sur des machines distinctes, je n'utiliserais pas de socket pour la communication. L'intention normale avec threads est qu'ils devraient garder les frais généraux au minimum; les prises ne correspondent pas très bien à cela. Si vous traversez les frontières d'une machine, beaucoup plus de surcharge (communication réseau) devient presque inévitable, et dans ce cas, l'utilisation de sockets au lieu d'une autre API réseau ne fait pas beaucoup de différence. Notez également que pour le travail sur plusieurs machines, vous devez en faire un peu plus en général, en rassemblant les données les unes par rapport aux autres, et ainsi de suite.

En supposant que vous vous en teniez à une seule machine, j'utiliserais une sorte de file d'attente thread-safe au lieu d'une socket. J'ai posté un dans un previous answer que vous pourriez trouver utile. Cela inclut un exemple de code qui crée un pool de threads pour les tâches de service dans la file d'attente.

+0

Mon serveur sera une machine linux (probablement un serveur ubuntu), savez-vous s'il y a des API de pool de threads disponibles? Si nécessaire je peux utiliser windows, mais avec l'absence d'une fonction poll(), je préférerais rester à l'écart ... *** Je le garde sur une seule machine. J'aime l'implémentation de votre file d'attente, je vais essayer. *** Nous vous remercions de votre réponse. – ultifinitus

+0

@ultifinitus: Cette implémentation de file d'attente particulière utilise des fonctions Windows, donc cela ne fonctionnera pas sous Linux. Vous voulez/devez remplacer les appels de fonction Windows par des équivalents pthreads (ce qui n'est pas entièrement simple). Boost a une implémentation "future" C++ que vous pourriez trouver utile (c'est fondamentalement une API de haut niveau pour un pool de threads). Je ne suis pas sûr, mais je crois me rappeler que quelques-unes des versions les plus récentes de gcc ont des futures dans la bibliothèque standard (elles font partie de la nouvelle norme C++ 11). –

+0

Je pense que mon plan, à cette seconde est de faire un pool de threads horriblement simple, si rien d'autre pour voir ce que les gains de performance avec mes compétences maigres viendront. *** Je me pencherai sur les contrats à terme *** J'ai de l'expérience avec les threads dans les systèmes Windows et Posix. *** pour l'instant je vais juste faire une classe manager, donc quand mon serveur reçoit un message, il peut le lancer au manager qui peut diviser les résultats en mes threads ... Merci encore. – ultifinitus

2

Y a-t-il une bibliothèque à utiliser? Eh bien, très certainement, sinon vous ne réaliserez pas ce que vous voulez en C++ standard. Cela soulève la question de savoir quelle plate-forme vous voulez utiliser ... utilisez-vous Windows ou un peu de Linux? Si vous utilisez Windows, vous pouvez utiliser les threads Windows et Win Socks 2. Si Linux vous pouvez essayer le threading Posix, et pour le réseautage je ne suis pas exactement sûr. Cependant, vous pouvez simplement utiliser les bibliothèques Boost pour faire tout cela, et cela devrait fonctionner sur Windows et sur votre système d'exploitation Linux. En ce qui concerne l'envoi d'un message, vous pouvez utiliser un mutex pour votre file d'attente, et simplement avoir une fonction de réception qui le verrouille et ajoute le message, qui fonctionne pour les deux messages entrants en réseau depuis le socket sur n'importe quel thread et pour d'autres threads souhaitant envoyer un message à ce thread. N'oubliez pas non plus, lorsque le thread traite des messages, vous voulez également verrouiller le mutex; Chaque fois que vous accédez à cette file d'attente, vous devez la verrouiller pour éviter les erreurs de collision/données.

+0

Il sera sur un système compatible Posix, plus que probable. Désolé de ne pas l'avoir dit, je vais aller de l'avant et éditer. – ultifinitus

2

Puisque vous utilisez des sockets, vous devrez utiliser quelque chose comme select ou poll pour attendre l'activité de socket. Donc, pour la communication inter-thread (itc), quelque chose qui utilise un descripteur de fichier sera très utile. Cela peut être une paire ou des tuyaux ou un socket de domaine Unix.

Vous aurez alors votre thread principal accepter une nouvelle connexion et utiliser votre mécanisme itc pour passer le nouveau descripteur de fichier au thread de travail. Le thread de travail ajoutera ensuite le nouveau descripteur de fichier à la boucle select/poll.

Si vous vous connectez et attendez sur un serveur dorsal (comme une base de données), vous pouvez décider de bloquer en attendant que le recv se termine bien que vous devriez probablement éviter cela. Votre serveur sera plus réactif si vous utilisez une machine d'état et retransformez votre pile au look select (après avoir ajouté le descripteur de fichier backend à la boucle select/poll). Cela facilitera le contrôle de votre thread de travail par votre thread principal. Si vous êtes intelligent, vos threads peuvent traiter plus d'une requête à la fois et avec seulement une poignée de thread, vous devriez avoir un serveur très évolutif. Essayez d'éviter d'utiliser des sémaphores ou des mutex pour itc et envoyez plutôt toutes les demandes via vos pipes itc ou vos sockets de domaine Unix. Vous allez vous épargner beaucoup de maux de cœur avec les conditions de course.

+0

J'utilise poll sur le système pour recevoir des entrées sur le thread principal, et je pensais simplement attendre sur le sondage, puis jeter les descripteurs de fichiers dans des discussions spécifiques. Je veux que mon serveur gère plus de 1000 clients à la fois, savez-vous à quel point ce système est évolutif? – ultifinitus

+0

Je voudrais alors essayer d'éviter d'utiliser un thread par session, mais plutôt avoir plusieurs sessions par thread. L'astuce consiste à s'assurer que les threads ne bloquent que lors du sondage. La raison de plusieurs threads devient alors uniquement pour s'assurer que tous les cœurs de CPU sont occupés à tout moment. Si vous n'avez toujours pas assez de jus dans le système, vous devrez peut-être envisager une sorte d'équilibrage de charge avec plusieurs serveurs. – doron

Questions connexes