Fork(), kill() et wait() ...

LocalStone Messages postés 514 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 1 mars 2009 - 15 nov. 2007 à 01:06
adduke Messages postés 4 Date d'inscription mardi 2 novembre 2004 Statut Membre Dernière intervention 5 février 2008 - 5 févr. 2008 à 14:17
Salut à tous,

Alors voilà, je suis face à un problème qui me prend la tête depuis au
moins une heure, mais je ne trouve vraiment pas de solution ni
d'explication. Je suis sur que c'est pas grand chose, mais bon ...

En fait, je débute en programmation système et donc là j'en suis au
routage des signaux. Donc j'ai en fait un processus père, qui crée un
processus fils. Dans le processus père, je déroute le signal SIGTERM
pour qu'un message soit affiché lorsqu'il reçoit un tel signal. C'est
le fils qui s'occupe d'envoyer le signal ...

En fait, c'est pas ça qui me pose un soucis, mais c'est la
synchronisation à la fin entre le père et le fils : je veux que le père
se termine uniquement lorsque le fils est terminé. Il n'y a qu'un seul
fils, donc j'utilise qu'un seul wait. Pourtant, lorsque le fils envoie
SIGTERM au père, le wait est débloqué ... Comment cela ce fait-ce ?

D'après le peu que j'ai lu, cela est du au fait que le wait attend non
pas la fin d'un processus, mais son changement d'état ... Mais j'avoue
que j'ai pas trop compris en quoi le fait de lancer un signal
correspond à un changement d'état.

Si quelqu'un peut m'expliquer, ce serait vraiment sympa !

Je met en annexe mon petit bout de code :
#include <stdio.h>

#include <signal.h>

#include

#include <errno.h>

#include <stdlib.h>

#include <sys/wait.h>


#define TEMPS_ATTENTE 5


void executerReactionSignal(int);


int main(void)

{

   pid_t intPidPere, intPidFils;


   intPidPere = getpid();


   intPidFils = fork();

   switch(intPidFils)

   {

      case -1 :

         printf("[Père#%d] Il y a eu une erreur lors du fork(). \n", intPidPere);

         exit(-1);

         break;

     

      case 0 :

         intPidFils = getpid();

         intPidPere = getppid();        

         printf("[Fils#%d] Je suis Fils#%d, issu de Père#%d ! \n", intPidFils, intPidFils, intPidPere);


         printf("[Fils#%d] J'envoie le signal %d à Père#%d dans %d
secondes. \n", intPidFils, SIGTERM, intPidPere, TEMPS_ATTENTE);

         sleep(TEMPS_ATTENTE);        

         if(kill(intPidPere, SIGTERM) == -1)

         {

            printf("[Fils#%d] Erreur lors de l'envoi du signal %d à Père#%d. \n", intPidFils, SIGTERM, intPidPere);

         }

         else

         {

            printf("[Fils#%d] Signal %d envoyé ! \n", intPidFils, SIGTERM);

         }


         sleep(TEMPS_ATTENTE);      


         printf("[Fils#%d] J'envoie le signal %d à Père#%d dans %d
secondes. \n", intPidFils, SIGTERM, intPidPere, TEMPS_ATTENTE);

         sleep(TEMPS_ATTENTE);

         if(kill(intPidPere, SIGTERM) == -1)

         {

            printf("[Fils#%d] Erreur lors de l'envoi du signal %d à Père#%d. \n", intPidFils, SIGTERM, intPidPere);

         }

         else

         {

            printf("[Fils#%d] Signal %d envoyé ! \n", intPidFils, SIGTERM);

         }

        

         printf("[Fils#%d] J'ai fini ! \n", intPidFils);

         exit(0);       

         break;


      default :                 

         printf("[Père#%d] Je suis Père#%d ! \n", intPidPere, intPidPere);

        

         struct sigaction stcReaction;

         stcReaction.sa_handler = executerReactionSignal;

         stcReaction.sa_flags = 0;


         printf("[Père#%d] Je déroute le signal %d. \n", intPidPere, SIGTERM);

         if(sigaction(SIGTERM, &stcReaction, NULL) == -1)

         {

            printf("[Père#%d] Il y a eu une erreur lors de sigaction() pour le signal %d. \n", intPidPere, SIGTERM);

         }        


         printf("[Père#%d] Je déroute le signal %d. \n", intPidPere, SIGKILL);

         if(sigaction(SIGKILL, &stcReaction, NULL) == -1)

         {

            printf("[Père#%d] Il y a eu une erreur lors de sigaction() pour le signal %d. \n", intPidPere, SIGKILL);

         }           


         printf("[Père#%d] J'attends Fils#%d. \n", intPidPere, intPidFils);                 

        

         wait(NULL); // Pourquoi l'envoi d'un signal de la part du fils débloque le wait ? Comment faire pour palier à ça ?

         wait(NULL);


         printf("[Père#%d] Fils#%d s'est terminé. \n", intPidPere, intPidFils);        

         break;

   }


   return 0;

}


void executerReactionSignal(int intSignal)

{

   pid_t intPidPere = getpid();

   printf("[Père#%d] Je viens de recevoir le signal %d. \n", intPidPere, intSignal);

}

Merci beaucoup pour votre aide !
LocalStone

1 réponse

adduke Messages postés 4 Date d'inscription mardi 2 novembre 2004 Statut Membre Dernière intervention 5 février 2008
5 févr. 2008 à 14:17
Salut,

Si ça peut d'aider ...
http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man2/pause.2.html
http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man2/wait.2.html
http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man/manfr.php?ptd=man3/index.html

Dixit 'WAIT' :

La fonction
wait suspend l'exécution du processus courant jusqu'à ce qu'un enfant se termine, OU jusqu'à ce qu'un signal à intercepter arrive.

@+,
Dukyduke
0
Rejoignez-nous