2 votes

pthread pool, C++

Je travaille sur un programme de réseau utilisant C++ et j'aimerais mettre en place un pool de pthreads. Chaque fois que je recevrai un événement du socket de réception, je placerai les données dans la file d'attente du pool de threads. Je pense créer 5 threads séparés qui vérifieront constamment la file d'attente pour voir s'il y a des données entrantes à faire.

Il s'agit d'un sujet assez simple, mais je ne suis pas un expert et j'aimerais entendre tout ce qui pourrait m'aider à le mettre en œuvre.

Veuillez me faire part de tous les tutoriels, références ou problèmes que je devrais connaître.

4voto

Sam Miller Points 14976

Utilice Boost.Asio et avoir chacun filetage dans le pool invoquent io_service::run() .

Plusieurs threads peuvent appeler io_service::run() pour mettre en place un pool de threads à partir desquels les gestionnaires d'achèvement peuvent être invoqués. Cette approche peut également également être utilisée avec io_service::post() pour utiliser un moyen d'effectuer toute tâche de calcul tâches de calcul à travers un pool de threads.

Notez que tous les fils qui ont rejoint le pool d'un io_service sont considérés comme des équivalents, et le io_service peut distribuer le travail entre eux de manière de manière arbitraire.

1voto

Loki Astari Points 116129

Avant de commencer.
Utiliser boost::threads

Si vous voulez savoir comment le faire avec les pthreads, vous devez utiliser les variables de condition des pthreads. Celles-ci vous permettent de suspendre les threads qui attendent du travail sans consommer de CPU.

Lorsqu'un élément de travail est ajouté à la file d'attente, vous signalez la variable de condition et un pthread sera libéré de la variable de condition, ce qui lui permettra de prendre un élément de la file d'attente. Lorsque le thread a fini de traiter l'élément de travail, il retourne à la variable de condition pour attendre le prochain élément de travail.

La boucle principale pour les fils de la boucle devrait ressembler à ceci ;

ThreadWorkLoop()                   // The function that all the pool threads run. 
{
    while(poolRunnin)
    {
        WorkItem = getWorkItem(); // Get an item from the queue. This suspends until an item 
        WorkItem->run();          // is available then you can run it.
    }
}
GetWorkItem()
{
    Locker  lock(mutex);                // RAII: Lock/unlock mutex
    while(workQueue.size() == 0)
    {
        conditionVariable.wait(mutex);  // Waiting on a condition variable suspends a thread
    }                                   // until the condition variable is signalled.
                                        // Note: the mutex is unlocked while the thread is suspended
    return workQueue.popItem();
}
AddItemToQueue(item)
{
    Locker lock(mutex);
    workQueue.pushItem(item);
    conditionVariable.signal();        // Release a thread from the condition variable.
}

0voto

hexa Points 4942

Demandez au thread de réception de pousser les données dans la file d'attente et aux 5 threads de la vider. Protégez la file d'attente avec un mutex et laissez-les se "battre" pour les données.

Il faut également prévoir un usleep() ou un pthread_yield() dans la boucle principale du fil de travail.

0voto

MK. Points 11889

Vous aurez besoin d'un mutex et d'une variable conditionnelle. Le mutex protégera votre file d'attente de travaux et lorsque les threads récepteurs ajouteront un travail à la file d'attente, il signalera la variable conditionnelle. Les threads travailleurs attendront la variable conditionnelle et se réveilleront lorsqu'elle sera signalée.

0voto

Michael Anderson Points 21181

Boost asio est une bonne solution.

Mais si vous ne voulez pas l'utiliser (ou si vous ne pouvez pas l'utiliser pour une raison quelconque), vous voudrez probablement utiliser une implémentation basée sur un sémaphore.

Vous pouvez trouver une implémentation de file d'attente multithread basée sur les sémaphores que j'utilise ici :

https://gist.github.com/482342

La raison de l'utilisation des sémaphores est que vous pouvez éviter que les threads de travail soient continuellement interrogés, et les faire réveiller par le système d'exploitation lorsqu'il y a du travail à faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X