Mon application est constituée du processus principal et de deux threads, tous s'exécutant simultanément et utilisant trois FIFO:Comment synchroniser trois threads?
Les fifo-q sont Qmain, Q1 et Q2. En interne, les files d'attente utilisent chacune un compteur qui est incrémenté lorsqu'un élément est placé dans la file d'attente et décrémenté lorsqu'un élément est «extrait» de la file d'attente.
Le traitement comporte deux fils,
QMaster, qui obtiennent de Q1 et Q2, et mis en Qmain,
Monitor, qui a mis en Q2,
et le processus principal, qui obtenir de Qmain et mis en Q1 . La boucle QMaster-thread vérifie consécutivement les compteurs de Q1 et Q2 et si des éléments sont dans les q, ils les récupèrent et les placent dans Qmain.
La boucle Monitor-thread obtient des données de sources externes, les regroupe et les place dans Q2.
Le processus principal de l'application exécute également une boucle vérifiant le compte de Qmain, et si des éléments, obtenir un élément de Qmain à chaque itération de la boucle et le traiter plus loin. Au cours de ce traitement, place parfois un élément dans Q1 pour le traiter plus tard (lorsqu'il est obtenu à partir de Qmain à son tour).
Le problème:
J'ai implémenté tout comme décrit ci-dessus, et cela fonctionne pour un temps aléatoire (court) puis se bloque. J'ai réussi à identifier la source de l'écrasement de se produire dans l'incrément/décrément du compte d'un fifo-q (il peut arriver dans l'un d'entre eux).
Ce que j'ai essayé:
En utilisant trois de mutex: QMAIN_LOCK, Q1_LOCK et Q2_LOCK, que je verrouille chaque fois que get/put opération se fait sur une fifo-q pertinente. Résultat: l'application ne démarre pas, elle se bloque.
Le processus principal doit continuer à s'exécuter tout le temps, ne doit pas être bloqué sur un 'read' (named-pipes échoue, socketpair échoue).
Un conseil?
Je pense que je ne suis pas en train d'implémenter correctement le mutex, comment cela devrait-il être fait?
(Tous les commentaires sur l'amélioration de la conception ci-dessus également les bienvenus)
[modifier] ci-dessous sont les processus et la fifo-q-modèle:
Où & comment, dans ce que je devrais placer pour éviter les problèmes du mutex décrits ci-dessus ?
main-process:
...
start thread QMaster
start thread Monitor
...
while (!quit)
{
...
if (Qmain.count() > 0)
{
X = Qmain.get();
process(X)
delete X;
}
...
//at some random time:
Q2.put(Y);
...
}
Monitor:
{
while (1)
{
//obtain & package data
Q2.put(data)
}
}
QMaster:
{
while(1)
{
if (Q1.count() > 0)
Qmain.put(Q1.get());
if (Q2.count() > 0)
Qmain.put(Q2.get());
}
}
fifo_q:
template < class X* > class fifo_q
{
struct item
{
X* data;
item *next;
item() { data=NULL; next=NULL; }
}
item *head, *tail;
int count;
public:
fifo_q() { head=tail=NULL; count=0; }
~fifo_q() { clear(); /*deletes all items*/ }
void put(X x) { item i=new item(); (... adds to tail...); count++; }
X* get() { X *d = h.data; (...deletes head ...); count--; return d; }
clear() {...}
};
Comment utilisez-vous les mutex n'enveloppent que l'incrément et décrément avez-vous pensé à utiliser un secion critique – rerun
J'ai vu "section critique" mentionné quand je googlé - s'il vous plaît mettre en place une réponse sur la façon dont vous le feriez mettre en œuvre pour ce qui précède, ou au moins pointer moi au bon matériel d'étude. – slashmais
Le système se bloque-t-il sans les mutex? Quand il se bloque, certaines files d'attente sont-elles pleines? – mouviciel