Bonjour à tous.
J'essaye de comprendre comment fonctionne les signaux sous Unix.
Pour ce faire, j'ai repris le livre de Jean-Marie Rifflet "La programmation sous UNIX" (3ième édition) et en particulier le chapitre 14 consacré à "La gestion des signaux".
J'ai repris l'exemple du paragraphe 14.8.2 consacré à "La primitive sigsuspend". Voici l'exemple :
Je l'ai légèrement modifié en dissociant les variables mask et action pour chaque processus.
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 #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> pid_t pid_fils; /*******************************/ /* */ /* Handler des Signaux */ /* */ /*******************************/ void handler_pere(int signo) { static int nbre_recu = 0; switch (signo) { case SIGUSR1: nbre_recu++; break; default: printf("\nNombre d'exemplaires reçus ..: %d\n", nbre_recu); exit(0); break; } } void handler_fils(int signo) { static int nbre_envoye = 0; switch (signo) { case SIGUSR1: nbre_envoye++; break; default: printf("Nombre d'exemplaires envoyés : %d\n", nbre_envoye); exit(0); } } /********************************/ /* */ /* Procédure Principale */ /* */ /********************************/ int main(void) { sigset_t mask1; struct sigaction action1; printf("Début du processus Père\n"); sigemptyset(&mask1); // sigaddset(&mask1, SIGUSR1); sigprocmask(SIG_BLOCK, &mask1, NULL); action1.sa_handler = handler_pere; sigaction(SIGUSR1, &action1, NULL); sigaction(SIGINT, &action1, NULL); sigemptyset(&mask1); sigprocmask(SIG_BLOCK, &mask1, NULL); if ((pid_fils = fork()) == 0) { /*========================*/ /* Processus Fils */ /*========================*/ sigset_t mask2; struct sigaction action2; printf("Début du processus Fils\n"); sigemptyset(&mask2); sigprocmask(SIG_BLOCK, &mask2, NULL); action2.sa_handler = handler_fils; sigaction(SIGUSR1, &action2, NULL); sigaction(SIGINT, &action2, NULL); for (int i=0; i<100000; i++) { kill(getppid(), SIGUSR1); sigsuspend(&mask2); } printf("Fin du processus Fils\n"); exit(0); } for (int i=0; i<100000; i++) { sigsuspend(&mask1); kill(pid_fils, SIGUSR1); } printf("Fin du processus Père\n"); exit(0); }
A vrai dire, cela ne change rien à mon problème.
Quand je le lance tel quel, et que je compte dans ma tête jusqu'à 10, je tape au clavier un ctrl+c pour provoquer un "SIGINT".
Voici le résultat :
Si maintenant je supprime le commentaire "//" et que je lance à nouveau le programme, dans les mêmes conditions, voici le nouveau résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 ~/Prog_C/ex_04> signal Début du processus Père Début du processus Fils ^C Nombre d'exemplaires reçus ..: 49 Nombre d'exemplaires envoyés : 49 ~/Prog_C/ex_04>
Comme vous pouvez le constater, avec le commentaire, le nombre de signaux est très faible (49 dans cet exemple), alors sans le commentaire, le nombre de signaux est bien plus important (94612).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 ~/Prog_C/ex_04> signal Début du processus Père Début du processus Fils ^C Nombre d'exemplaires reçus ..: 94612 Nombre d'exemplaires envoyés : 94611 ~/Prog_C/ex_04> signal
1) en quoi le fait de mettre la ligne en commentaire ou pas, a une influence sur la rapidité du traitement des signaux ?
2) pourquoi écrire dans le programme, pour le processus 1, d'abord l'interdiction du signal SIGUSR1", puis après l'action, supprimer cette interdiction ?
Autrement dit, je ne comprends pas l'intérêt de déclarer un blocage d'un signal, pour ensuite ne plus le bloquer.
Merci.
@+
Partager