Reprise de processus après un SIG_BLOCK dans un handler?
Reprise de processus après un SIG_BLOCK dans un handler? - C - Programmation
MarshPosté 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 :
#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
elseif(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
elseif(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
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:
Voici la sortie sur la console
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