Pages : 1
#1 Le 23/10/2006, à 18:29
- trucutu_
Une petite question de temps réel
Bonjour,
Je cherche à synchroniser deux processus "lourds" sous UNIX/Linux avec un time out (au cas où le processus attendu plante), et j'ai un petit problème.
Si j'utilise des sémaphores, la fonction d'attente n'est pas prévue pour contrôler un "time out" (pas d'option prévue), donc l'attente peut être infinie... Et si j'utilise des mutex avec des attentes de conditions, ce dispositif n'est appramment prévu que pour les threads (processus "leger")...
Quoique, le programme dispose d'une shm. Par conséquent, je compte y insérer les mutex. Est-ce jouable ? (niveau fonctionnalité, performances et tout...)
Sinon, des personnes auraient-elles implantées ce genre de procédé d'une manière différente ? Je n'ose croire qu'aucun programmeur ne réalise des attentes entre deux processus sans créer des sécurités temporelles pour que le programme continu à s'executer ....
Voilà
Merci d'avance
#2 Le 23/10/2006, à 18:40
- guyver2
Re : Une petite question de temps réel
la fonction wait("pid du process a attendre"); devarait faire l'affaire.
elle permet a un processus lourd d'attendre la fin (normal ou erreur) d'un autre.
[edit] Argh, apres relecture de ton post je m'apperçoit que ce n'est pas forcement pour attendre la FIN d'un processus.
Si tu met un mutex dans la shm, les deux processus travaillerons sur le meme, c'est donc jouable.
A toi de t'arranger pour qu'aucun ne bloque en section critique...
[edit 2] je pense que des envois de signaux pourais faire l'affaire pour ce probleme. Si tu sait quel processus attend l'autre.
exemple: tu sais que p1 se terminera avant p2
quand p1 arrive au point de rencontre, tu l'endort
quand p2 arrive, il envois un signal a p1 qui se reveil. et zou
Dernière modification par guyver2 (Le 23/10/2006, à 18:50)
Croire est le meilleur moyen de ne jamais rien savoir
Mes jeux en C/C++
Hors ligne
#3 Le 23/10/2006, à 23:02
- trucutu_
Re : Une petite question de temps réel
Effectivement, l'attente peut se faire n'importe quand, de manière répétée et surtout, de manière indéfinie. C'est pour ça que le wait d'un sémaphore n'est pas satisfaisant.
La shm me semble jouable. Ce qui me fait peur, c'est qu'il y a déjà pas mal de chose dedans, et rajouter un tableau de mutex, qui plus est de type complexes, j'espère que ça ne va pas mettre le zouk...
Pour l'histoire des signaux, ca a déjà été envisagé et considéré comme inapproprié (le processus qui devrait attendre envoi déjà des signaux à ceux éventuellement attendus, et la contrainte est que la communication doit se faire uniquement dans ce sens...)
Ce qui me saoule, c'est de voir que l'attente avec time out pour un sémaphore a été implanté sur une architecture propriétaire dont je tairai le nom. Ca donnerai presque envie d'y retourner !! non, je plaisante.
Donc ce que je voudrais savoir, c'est si ce problème a déjà été rencontré et résolu sous Linux. Sachant qu'il y aurait la solution de faire une boucle while sur une la fonction trywait (non-bloquante), jusqu'à l'évolution correcte du sémaphore ou la fin d'un time out crée en mesurant le temps par exemple. Mais bon, ce n'est pas une solution que je trouve élégante (sachant qu'une autre contrainte c'est de ne pas faire de "polling" (boucle + sleep) sur un processus pour ne pas perdre le contrôle...)
Voili Voilou
Merci en tous cas pour cet élément de réponse
#4 Le 23/10/2006, à 23:48
- gene69
Re : Une petite question de temps réel
je comprend rien à ce que tu veux synchroniser. je vois mal comment un mutex peux ne pas faire l'affaire de toute façon.
il me semble que tu veuilles faire un watchdog. Dans ce cas il suffit que tu envoyes une message tous les X minisecondes... et aux bout de 15 secondes kill -s15 puis kill -9
Quand le berger est lâche, le loup chie de la laine.
A (draft) guide to UFO Alien-Invasion
Hors ligne
#5 Le 24/10/2006, à 01:30
- trucutu_
Re : Une petite question de temps réel
Ben, c'est pourtant pas compliqué !
Tu as un processus M (j'ai pas dit thread !!) qui en commande d'autres E par l'envoi de signaux. Il arrive que de temps en temps, les processus commandés E ne réagissent pas assez vite (les signaux sont envoyés de l'ordre de la ms) et les signaux sont envoyés trop tot.
Donc l'objectif, c'est de retarder l'envoi du signal, pendant ce temps, les processus E font leurs vie et le processus M ni voit que du feu quand il reprend la main.
Pour cela, une variable commune permet de constater le retard accumulé dans E et d'imposer une attente sur M. Ensuite, lors de la fin du retard le processus E (au passage, cela se passe dans un thread particulier du processus) libère l'attente et le processus M peut continuer. Sachant que l'attente doit être contrôlée en durée au cas où le processus M "ai planté" avant que se fasse la libération.
Maintenant, pas le droit à une fonction sleep pour ne pas perdre le contrôle, pas le droit de renvoyer un signal pour indiquer la fin du retard.
De plus, une recherche montre que les fonctions d'attentes des sémaphores (qui peuvent être communs à plusieurs processus) ne prennent pas en compte de time out, et les mutex (dont les fonctions d'attentes peuvent être contrôlées dans le temps) ne fonctionnent de base que pour les threads... Donc ma question est simple : on fait comment ?
On peut pas faire plus simple ... non ?
#6 Le 24/10/2006, à 08:53
- gene69
Re : Une petite question de temps réel
Bon ben de toute façon à tout moment il faut que tu ai un délais maximum entre deux tops entre le processus père et fils. Parce que sinon je ne sais pas comment tu constater le plantage du processus.
en réseau on utiliserai une poignée du genre TCP... je commence à comprendre... intéressant comme sujet.
Quand le berger est lâche, le loup chie de la laine.
A (draft) guide to UFO Alien-Invasion
Hors ligne
#7 Le 24/10/2006, à 13:12
- guyver2
Re : Une petite question de temps réel
j'utilise les fonctions P et V sur les mutex. P demande l'acces et V libere l'acces.
tu crée UN mutex (appelons le "rencontre") commun a tous (le M et les E). initialisé a 0;
tu crée une variable nbEnonFinis qui represente le nombre de E qui n'ont pas encore fini.
tu crée UN mutex (appelons le "Efinis") communs a tous les E qui régule l'acces a nbEnonFinis
losrque M doit attendre la fin des E il fait P(rencontre) et bloque puisque le mutex rencontre a été initialisé a 0.
lorsque un E arrive au pt de rencontre il fait
P(Efinis);
nbEnonFinis--;
if (nbEnonFinis == 0) V(rencontre); // le dernier E libere M.
V(Efinis);
et continue son chemin.
De cette façon M reste bloqué jusqu'a ce que tous les E aient passé le "checkpoint" et de plus les E sont indépendants d'une defaillance de M.
Croire est le meilleur moyen de ne jamais rien savoir
Mes jeux en C/C++
Hors ligne
#8 Le 24/10/2006, à 16:08
- trucutu_
Re : Une petite question de temps réel
gene69 : c'est prévu. En mode normal, si un processus E ne réagit pas au bout d'un certains nombres de signals, le thread incriminé se voit gratifié d'un pthread_kill
guyver2 : C'est exactement dans l'esprit de ce que je compte faire. Mais je vois deux problèmes à ta solution :
- Il faut que les mutex introduits soit bien "communs à tous" (et pour l'instant, tant que je n'ai pas testé, je ne considère pas ce point comme acquis)
- Il n'est pas garanti que les processus E atteigne le checkpoint (c'est plus les E que M qui ont des chances de défaillir...). D'où l'intrusion de time out pour le wait du coté du M.
Je suis actuellement en train d'implanter une solution. Je vous tiens au courant....
#9 Le 24/10/2006, à 17:12
- guyver2
Re : Une petite question de temps réel
- Il faut que les mutex introduits soit bien "communs à tous" (et pour l'instant, tant que je n'ai pas testé, je ne considère pas ce point comme acquis)
C'est justement ce que je suis en train de voir en cours. le passage de mutex entre processus lourds via des shm. Donc il n'y a pas de raison que ça foire a ce niveau.
- Il n'est pas garanti que les processus E atteigne le checkpoint (c'est plus les E que M qui ont des chances de défaillir...).
et
si un processus E ne réagit pas au bout d'un certains nombres de signals, le thread incriminé se voit gratifié d'un pthread_kill
pas de probleme, tu intercepte le signal reçut par E dans dans une fonction comme cela:
void signalKill(void)
{
P(Efinis);
nbEnonFinis--;
if (nbEnonFinis == 0) V(rencontre); // le dernier E libere M.
V(Efinis);
exit(1);
}
comme ça, ça fera comme si le processus était arrivé au checkpoint E meurt et M poursuit son chemin.
Dernière modification par guyver2 (Le 24/10/2006, à 17:15)
Croire est le meilleur moyen de ne jamais rien savoir
Mes jeux en C/C++
Hors ligne
#10 Le 24/10/2006, à 19:44
- trucutu_
Re : Une petite question de temps réel
Bon, pour l'histoire des shm, tu me rassures, ca veut dire que c'est envisageable en théorie. On verra demain en pratique.
Pour la solution, c'est un peu plus compliqué que ce que tu avances (au passage, le but est d'éviter au maximum d'envoyer le signal pthread_kill), mais bon, tu ne connais pas l'étendue du problème non plus (il ne faut pas attendre la fin de tous les E, mais d'un ou plusieurs, qui seront relancés ultérieurement). En fait, j'ai repris un exemple du livre "Programmation système en C sous Linux" (partie sur les exclusions mutuelles avec attentes conditionnées) , ca devrait marcher.
Chaque processeur E possède, via la shm, un mutex m une condition c et deux indicateurs (Efini et EenRetard)
Grosso Modo, ca donne :
dans M
si !Efini
EenRetard++
P(m,c,timeOut) ( mutex_lock + cond_timedwait + mutex_unlock )
puis continue normalement
dans E, lors de la mise a zero de Efini
si EenRetard
V(m,c) (mutex_lock + cond_signal + mutex_unlock )
EenRetard--