Reprise de processus après un SIG_BLOCK dans un handler?

Reprise de processus après un SIG_BLOCK dans un handler? - C - Programmation

Marsh Posté le 25-09-2010 à 15:04:18    

Bonjour,
 
Je suis sensé réaliser l'exercice suivant:
   -Je crée un Processus Fils qui crée un Processus Petit-Fils:
   -L’exécution de tous les processus, à l'exception du processus initial (Père), doit être suspendue.  
   -Le père affiche alors un message "Tous mes fils sont suspendus"
   -L’exécution des processus suspendus doit alors reprendre.  
   - ...
 
Je n'ai pas le droit d'utiliser le wait.
 
Le prof de TD nous a donné le raisonnent suivant.
 
-Je crée un processus Père qui crée un Processus Fils qui crée un Processus Petit-Fils:
-Le petit fils se stoppe via un signal "SIGSTOP" à lui-même.
-Le fils reçoit un signal SIGCHLD et se stoppe via un signal "SIGSTOP" à lui-même (Il se stoppe donc dans le handler).
-Le grand père reçoit un signal SIGCHLD et réveil son fils par un signal SIGCONT (Fils stoppé dans le handler).
...
 
Le problème est le suivant: lorsque le fils s'interrompt dans le handler, le signal envoyé par son père ne le réveil pas. Je ne sais pas comment est implémenté la gestion du signal SIGSTOP. Mais je pense que c'est le fait d'interrompre le processus dans un handler qui pose problème.
 
Voici le code:
 

Code :
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. #include <sys/wait.h>
  6. int PID = 0;
  7. int CPT = 0;
  8. /**
  9. * Handler du processus main sur le signal SIGCHLD du fils
  10. */
  11. void grandPereHandler(int sig)
  12. {
  13. // appel suite a l'arrêt du processus fils
  14. if(CPT == 0)
  15. {
  16.  printf("Grand Père: mon fils est stoppé je le réveil Pid du fils %d \n", PID);
  17.  // signal de "wakeup" au fils
  18.  kill(PID, SIGCONT);
  19. }
  20. // processus fils -> ZOMBI
  21. else
  22. {
  23.  // Libération du fils  
  24.  wait(NULL);
  25.  printf("Libération du fils \n" );
  26. }
  27. CPT++;
  28. }
  29. /**
  30. * Handler du processus père sur le signal SIGCHLD du fils
  31. */
  32. void filsHandler(int sig)
  33. {
  34. // appel suite a l'arrêt du processus fils
  35. if(CPT == 0)
  36. {
  37.  // Le processus se stoppe
  38.  printf("Mon petit-fils est stoppé, je me stoppe Pid: %d \n", getpid());
  39.  kill(getpid(), SIGSTOP);
  40.  printf("Je me réveil %d \n", getpid());
  41. }
  42. // processus fils -> ZOMBI
  43. else
  44. {
  45.  // Libération du fils
  46.  wait(NULL);
  47.  printf("Libération du fils \n" );
  48. }
  49. CPT++;
  50. }
  51. int main(int argc, char** argv)
  52. {
  53. printf("PID du grand père %d \n", getpid());
  54. int value = EXIT_SUCCESS;
  55. sigset_t sig_proc;
  56. struct sigaction action;
  57. // Handler du signal SIGCHLD
  58. sigemptyset(&sig_proc);
  59. action.sa_mask = sig_proc;
  60. action.sa_flags = 0;
  61. action.sa_handler = grandPereHandler;
  62. sigaction(SIGCHLD, &action, NULL);
  63. //  
  64. // On masque le signal SIGCHLD pour s'assurer que la variable  
  65. // globale PID soit remplie lorsque le père reçoit le signal
  66. //
  67. sigemptyset(&sig_proc);
  68. sigaddset(&sig_proc, SIGCHLD);
  69. sigprocmask(SIG_BLOCK, &sig_proc, NULL);
  70. if((PID = fork()) == -1)
  71. {
  72.  perror("Erreur fork" );
  73.  value = EXIT_FAILURE;
  74. }
  75. // Je suis dans le fils
  76. else if(PID == 0)
  77. {
  78.  printf("PID du fils %d \n", getpid());
  79.  // Démasque SIGCHLD
  80.  sigprocmask(SIG_UNBLOCK, &sig_proc, NULL);
  81.  action.sa_handler = filsHandler;
  82.  sigaction(SIGCHLD, &action, NULL);
  83.  if((PID = fork()) == -1)
  84.  {
  85.   perror("Erreur fork" );
  86.   value = EXIT_FAILURE;
  87.  }
  88.  // Je suis dans le petit-fils
  89.  else if(PID == 0)
  90.  {
  91.   printf("PID du petit-fils %d qui se stoppe \n", getpid());
  92.   // Je me stoppe
  93.   kill(getpid(), SIGSTOP);
  94.  }
  95. }
  96. // Je suis dans le père
  97. else
  98. {
  99.  // Démasque SIGCHLD
  100.  sigprocmask(SIG_UNBLOCK, &sig_proc, NULL);
  101. }
  102. return EXIT_SUCCESS;
  103. }


 
Voici la sortie sur la console
 

Code :
  1. PID du grand père 14516
  2. PID du fils 14517
  3. PID du petit-fils 14518 qui se stoppe
  4. Mon petit-fils est stoppé, je me stoppe Pid: 14517
  5. Grand Père: mon fils est stoppé je le réveil Pid du fils 14517


 
Nous pouvons voir que le fils ne se réveille jamais après le signal du grand père.
 
Merci d'avance de votre aide.


Message édité par Anonymouse le 25-09-2010 à 18:05:12
Reply

Marsh Posté le 25-09-2010 à 15:04:18   

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed