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 la fonction 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 : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 
#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 : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
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.