Anonymouse | 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 :
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <sys/wait.h>
- int PID = 0;
- int CPT = 0;
- /**
- * Handler du processus main sur le signal SIGCHLD du fils
- */
- void grandPereHandler(int sig)
- {
- // appel suite a l'arrêt du processus fils
- if(CPT == 0)
- {
- printf("Grand Père: mon fils est stoppé je le réveil Pid du fils %d \n", PID);
- // signal de "wakeup" au fils
- kill(PID, SIGCONT);
- }
- // processus fils -> ZOMBI
- else
- {
- // Libération du fils
- wait(NULL);
- printf("Libération du fils \n" );
- }
- CPT++;
- }
- /**
- * Handler du processus père sur le signal SIGCHLD du fils
- */
- void filsHandler(int sig)
- {
- // appel suite a l'arrêt du processus fils
- if(CPT == 0)
- {
- // Le processus se stoppe
- printf("Mon petit-fils est stoppé, je me stoppe Pid: %d \n", getpid());
- kill(getpid(), SIGSTOP);
- printf("Je me réveil %d \n", getpid());
- }
- // processus fils -> ZOMBI
- else
- {
- // Libération du fils
- wait(NULL);
- printf("Libération du fils \n" );
- }
- CPT++;
- }
- int main(int argc, char** argv)
- {
- printf("PID du grand père %d \n", getpid());
- int value = EXIT_SUCCESS;
- sigset_t sig_proc;
- struct sigaction action;
- // Handler du signal SIGCHLD
- sigemptyset(&sig_proc);
- action.sa_mask = sig_proc;
- action.sa_flags = 0;
- action.sa_handler = grandPereHandler;
- sigaction(SIGCHLD, &action, NULL);
- //
- // On masque le signal SIGCHLD pour s'assurer que la variable
- // globale PID soit remplie lorsque le père reçoit le signal
- //
- sigemptyset(&sig_proc);
- sigaddset(&sig_proc, SIGCHLD);
- sigprocmask(SIG_BLOCK, &sig_proc, NULL);
- if((PID = fork()) == -1)
- {
- perror("Erreur fork" );
- value = EXIT_FAILURE;
- }
- // Je suis dans le fils
- else if(PID == 0)
- {
- printf("PID du fils %d \n", getpid());
- // Démasque SIGCHLD
- sigprocmask(SIG_UNBLOCK, &sig_proc, NULL);
- action.sa_handler = filsHandler;
- sigaction(SIGCHLD, &action, NULL);
- if((PID = fork()) == -1)
- {
- perror("Erreur fork" );
- value = EXIT_FAILURE;
- }
- // Je suis dans le petit-fils
- else if(PID == 0)
- {
- printf("PID du petit-fils %d qui se stoppe \n", getpid());
- // Je me stoppe
- kill(getpid(), SIGSTOP);
- }
- }
- // Je suis dans le père
- else
- {
- // Démasque SIGCHLD
- sigprocmask(SIG_UNBLOCK, &sig_proc, NULL);
- }
- return EXIT_SUCCESS;
- }
|
Voici la sortie sur la console
Code :
- PID du grand père 14516
- PID du fils 14517
- PID du petit-fils 14518 qui se stoppe
- Mon petit-fils est stoppé, je me stoppe Pid: 14517
- 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
|