2010-06-04 5 views
1

J'ai cinq consommateurs et un producteur. Les cinq consommateurs produisent chacun des données différentes, provenant du producteur unique, pour ~ 10ms. Pendant ces 10ms, le producteur prépare les paramètres pour la sortie suivante. Lorsque les paramètres de sortie sont définis, je veux définir un drapeau demandant aux consommateurs de commencer la sortie suivante. Je veux seulement que le producteur produise quand les consommateurs produisent les données.C++: synchroniser 5 consommateurs à 1 producteur (multithread)

Je ne sais pas comment synchroniser les cinq consommateurs et le producteur unique. J'ai actuellement deux drapeaux, runFlag et doneFlag. Lorsqu'un consommateur lit les nouvelles données, je veux définir runFlag sur true pour que les calculs commencent, et je veux définir doneFlag sur false, car les calculs ne sont pas terminés. Cependant, si je mets doneFlag à false dans un consommateur, il peut être faux dans un autre consommateur avant que ce consommateur puisse vérifier le drapeau.

J'espère que ma question est assez spécifique. S'il vous plaît laissez-moi savoir s'il y a autre chose que je peux fournir. En outre, je cherche juste une idée générale de la façon de procéder. Je sais qu'il y a plusieurs façons de le faire, mais je ne sais pas quelle méthode fonctionnera le mieux.

Merci!

+0

Vous pouvez utiliser Boost Thread qui prend en charge le mutex partagé. [link] (http://www.boost.org/doc/libs/1_43_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.shared_lockable) –

Répondre

2

Vous aurez besoin de 2 événements et d'un nombre de références entières.

Quand le producteur a produit quelque chose il:

  • initie read_count = 0;
  • définit l'événement readme.
  • commence à attendre que l'événement soit terminé;

Les consommateurs attendent sur l'événement readme. Après avoir fait leur travail, ils incrémentent ATOMIQUEMENT read_count. Si read_count atteint le nombre de consommateurs, 5 dans votre cas, il définit l'événement completed. Ainsi, le producteur peut continuer et le cycle se répète.

+0

Merci, c'est exactement ce que je cherchais. – Dan

+0

Vous pouvez faire la même chose avec des sémaphores. – SigTerm

0

Il y a quelques années, j'ai dû créer un répartiteur de travail générique qui effectue un post-traitement. Ce n'est pas un producteur-consommateur exactement et peut être exagéré pour votre application, mais il peut vous donner quelques idées. J'aime particulièrement utiliser une paire de files d'attente partagées en mémoire, une file d'attente sortante et une file d'attente entrante, disposées comme un canal bidirectionnel. Si vous créez une classe de file d'attente qui a la synchronisation correcte pour la lecture et l'écriture, le producteur et les consommateurs peuvent devenir indépendants. Ils n'ont pas besoin de savoir comment se synchroniser les uns avec les autres. Vos données, connues du producteur et du consommateur, référencées dans une classe d'éléments de travail. La classe d'élément de travail contient tous les indicateurs d'état. Les données doivent également être thread safe.

Le producteur met en file d'attente des éléments de travail dans la file d'attente sortante et chaque consommateur supprime un élément de travail unique. Une fois le travail terminé, les indicateurs d'état sont mis à jour et l'élément de travail est renvoyé dans la file d'attente entrante pour être traité par le producteur.

IIRC, l'architecture ne contient que trois classes environ.