[Programmation système] Comment synchroniser des signaux entre processus?

biglittlekiss Messages postés 2 Date d'inscription mardi 3 février 2004 Statut Membre Dernière intervention 9 avril 2004 - 9 avril 2004 à 20:21
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 - 10 avril 2004 à 05:01
Bonjour,

Voila je fait cet exercice et je bloque sur l'execution ens équence des processus.

Exercice:
Un processus père, construit 2 processus fils, place leur pid dans 2 fichiers et s'endort immédiatement sur un wait. Le père se termine après la terminaison des fils.
Les 2 processus Pa et Pb sont identiques: ils executent 3 sequences.
A la fin de chaque séquence, le fils actif envoie in signal SIGUSR1 à l'autre fils et s'endort en attendant d'être réveillé par un signal SIGSUSR2.
L'autre fils réveillé, agit de même, il execute sa séquence et ensuite envoie le signal SIGUSR2 et s'endort.
Chacun des processus fils exécute ses 3 séquences et ensuite se termine.
(donc les sequence se dérouleront dans cette ordre: Sa1, Sb1, Sa2, Sb2, Sa3, Sb3).

Pour ma part, j'ai programmer ça, mais je ne vois pas pourquoi mes processus ne marche pas en sequence l'un après l'autre.
Au secourrrrrrrrrr

#include <stdio.h>		/* printf */
#include <stdlib.h>		/* exit */
#include 		/* Fork write sleep */
#include <errno.h>		/* Obtenir nuemro erreur */
#include <sys/wait.h>	/* Wait WIFEXITED*/
#include <sys/types.h>	/* Wait kill*/
#include <signal.h>		/* SIGUSR1 SIGUSR2... kill */
int nbrseqPa 3, nbrseqPb 3, retcodePa = 15, retcodePb = 16;int nbr1 1, nbr2 1;
int SIGSUSR2;

struct sigaction mode_signal;

void signal_for_son(int signal){

if (signal == SIGUSR1) { printf("Je suis dans SIGUSR1 Je vais réveiller mon frère Pb...");}
if (signal == SIGUSR2) { printf("Je suis dans SIGUSR2 Je vais réveiller mon frère Pa...");}

printf("\nRéveil en cours...\n\n");
kill(getpid(), SIGSUSR2);
}

int main(){

FILE * sortie_Pa; /* Déclaration d'un fichier de sortie pour le pid de Pa */
FILE * sortie_Pb; /* Déclaration d'un fichier de sortie pour le pid de Pb */
sortie_Pa = fopen( "Pid_Pa.txt" , "w"); /* Ouverture du fichier Pid_Pa.txt en mode ecriture */
sortie_Pb = fopen( "Pid_Pb.txt" , "w"); /* Ouverture du fichier Pid_Pb.txt en mode ecriture */

//##############################
//##############################
mode_signal.sa_handler = signal_for_son;
mode_signal.sa_flags   = 0;
sigemptyset(&mode_signal.sa_mask);
sigaction(SIGUSR1, &mode_signal, NULL); /* set traitement_signal pour SIGUSR1 */
sigaction(SIGUSR2, &mode_signal, NULL); /* set traitement_signal pour SIGUSR2 */
sigaction(SIGSUSR2, &mode_signal, NULL); /* set traitement_signal pour SIGSUSR2 */
//##############################
//##############################

/* Test de la création de Pid_Pa.txt et de Pid_Pb.txt */
if ( sortie_Pa == NULL) { 
printf("****Erreur création du fichier sortie_Pa.txt impossible***"); exit(EXIT_FAILURE);
}
if ( sortie_Pb == NULL) { 
printf("****Erreur création du fichier sortie_Pb.txt impossible***"); exit(EXIT_FAILURE);
}

printf ("\n\nJe suis PIPE.exe, processus père, titulaire du pid: %d \n", (int) getpid());
printf ("Je vais enfanter 2 fils: Pa et Pb, qui vont travailler en séquence\n\n");

/* Creation du processus Pa */
pid_t Pa;
switch (Pa = fork())
{
case -1 : printf("Erreur lors de la création de Pa! \nerrno= %d\n",errno); exit(EXIT_FAILURE);
case  0 :
fprintf(sortie_Pa, "Pa:  No= %3d PID=%3d Pere= %d",Pa,getpid(), getppid() );

while (nbr1 <= nbrseqPa){
printf("Moi Pa fils de PIPE.exe, j'execute ma séquence %d \n\n",nbr1);

if (nbr1 < nbrseqPa) kill(getpid(), SIGUSR1);
nbr1++;
pause(); /* Mise en pause de Pa en attente d'un signal */
}
exit(retcodePa);
}

/* Creation du processus Pb */
pid_t Pb;
switch (Pb = fork())
{
case -1 : printf("Erreur lors de la création de Pb! \nerrno= %d\n",errno); exit(EXIT_FAILURE);
case  0 :
fprintf(sortie_Pb, "Pb:  No= %3d PID=%3d Pere= %d",Pb,getpid(), getppid() );

while (nbr2 <= nbrseqPb){
printf("Moi Pb fils de PIPE.exe, j'execute ma séquence %d \n\n",nbr2);

if (nbr2 < nbrseqPb) kill(getpid(), SIGUSR2);
nbr2++;
pause(); /* Mise en pause de Pb en attente d'un signal */
}
exit(retcodePb);
}

/* Execution du processus père */
int attendcodePa, attendcodePb;

wait (&attendcodePa);/* On attend que Pa se finisse...*/
wait (&attendcodePb);/* On attend que Pb se finisse avant de commencer le code du père */

/* On affiche un message qu'au moin un des fils à mal travaillé */
if ( (WIFEXITED(attendcodePa) <= 0) && (WIFEXITED(attendcodePa) <= 0) ){
printf("Mes fils ne savent même pas travailler en partenaria se sont des incapables \n");
exit(EXIT_FAILURE);
}
/* On affiche que Pa et Pb ont bien accomplient leur job */
if ( (WIFEXITED(attendcodePa) > 0) && (WIFEXITED(attendcodePa) > 0) ){
printf("\nLes pid respectifs de Pa et Pb ont été enregistré dans Pid_Pa.txt et Pid_Pb.txt\n");
printf("\n\nMes fils ont bien travaillé! \n");
}
printf("Je peux maintenant arrêter mon exécution\n\n\n");
exit(EXIT_SUCCESS); //
}

1 réponse

Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
10 avril 2004 à 05:01
j'ai pas regarder ton code exactement mais si tu fais de processus legers (pthread_create, ...), tu poura utiliser les commandes signal de thread (pthread_cond_...) ou alors fais les communiquer par un tube (pipe) si tu garde des processus lourds.
0
Rejoignez-nous