TP 10 (prog. système) Signaux - IUT d'Arles
TP 10 (prog. système) Signaux - IUT d'Arles
TP 10 (prog. système) Signaux - IUT d'Arles
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Iut Arles / A1SE<br />
Systèmes d’exploitation<br />
<strong>TP</strong> <strong>10</strong> (<strong>prog</strong>. système) <strong>Signaux</strong><br />
Il existe sous Linux 64 signaux différents qui permettent de faire passer un message et<br />
éventuellement (cf 2ème exemple) des informations. Les 32 premiers signaux sont réservés au<br />
systèmes (SIGCHLD, SIGHINT, SIGSEGV, SIGPWR, ...) et permettent la communication entre<br />
processus. La liste des signaux est disponible par la commande « kill -l » :<br />
1) SIGHUP<br />
2) SIGINT<br />
3) SIGQUIT<br />
4) SIGILL<br />
5) SIGTRAP<br />
6) SIGABRT<br />
7) SIGBUS<br />
8) SIGFPE<br />
9) SIGKILL<br />
<strong>10</strong>) SIGUSR1<br />
11) SIGSEGV<br />
12) SIGUSR2<br />
13) SIGPIPE<br />
14) SIGALRM<br />
15) SIGTERM<br />
16) SIGSTKFLT<br />
17) SIGCHLD<br />
18) SIGCONT<br />
19) SIGSTOP<br />
20) SIGTS<strong>TP</strong><br />
21) SIGTTIN<br />
22) SIGTTOU<br />
23) SIGURG<br />
24) SIGXCPU<br />
25) SIGXFSZ<br />
26) SIGVTALRM<br />
27) SIGPROF<br />
28) SIGWINCH<br />
29) SIGIO<br />
30) SIGPWR<br />
31) SIGSYS<br />
34) SIGRTMIN<br />
35) SIGRTMIN+1<br />
36) SIGRTMIN+2<br />
37) SIGRTMIN+3<br />
38) SIGRTMIN+4<br />
39) SIGRTMIN+5<br />
40) SIGRTMIN+6<br />
41) SIGRTMIN+7<br />
42) SIGRTMIN+8<br />
43) SIGRTMIN+9<br />
44) SIGRTMIN+<strong>10</strong><br />
45) SIGRTMIN+11<br />
46) SIGRTMIN+12<br />
47) SIGRTMIN+13<br />
48) SIGRTMIN+14<br />
49) SIGRTMIN+15<br />
50) SIGRTMAX-14<br />
51) SIGRTMAX-13<br />
52) SIGRTMAX-12<br />
53) SIGRTMAX-11<br />
54) SIGRTMAX-<strong>10</strong><br />
55) SIGRTMAX-9<br />
56) SIGRTMAX-8<br />
57) SIGRTMAX-7<br />
58) SIGRTMAX-6<br />
59) SIGRTMAX-5<br />
60) SIGRTMAX-4<br />
61) SIGRTMAX-3<br />
62) SIGRTMAX-2<br />
63) SIGRTMAX-1<br />
64) SIGRTMAX<br />
Par exemple pour tuer un processus, la commande « kill – 9 3271 » envoie en fait le signal<br />
« SIGKILL » au processus numéro 3271. Le signal « SIGINT » est une interruption par<br />
l'utilisateur (par exemple lors de l'appui de « CTRL-C » dans une commande). Pour avoir la<br />
liste descriptive de chaque signal, consultez le manuel de la fonction « signal » (section 7 du<br />
man : « man 7 signal »).<br />
1. 1er exercice : test simple sur CTRL-C<br />
Le traitement des signaux se fait en déclarant au début du « main() » les signaux<br />
traités par la primitive « signal(...) ». Le code de cet exemple est dans<br />
« test_signal_simple.cpp » des sources du <strong>TP</strong>. Le principe est d'attendre un signal (la<br />
fonction « pause() » endort le processus jusqu'à la réception d'un signal) et si on reçoit<br />
« SIGINT » (signal d'interruption), on sorte du <strong>prog</strong>ramme par un « exit() ».<br />
Évidemment cette façon de faire n'est pas très belle puisqu'on n'aura pas le temps de<br />
fermer les fichiers, rendre les ressources du <strong>prog</strong>ramme (fuites de mémoires et tutti<br />
quanti) :<br />
//fonction de traitement des signaux<br />
void traitement_signaux(const int num_signal) {<br />
switch (num_signal) {<br />
//Qu'est-ce qu'on fait si on reçoit un signal d'appui sur CTRL-C ?<br />
case SIGINT : std::cerr
Iut Arles / A1SE<br />
Systèmes d’exploitation<br />
}<br />
note : la fonction « atexit » dans le fichier source peut vous aider pour désaloouer les<br />
ressources avant de sortir du <strong>prog</strong>ramme.<br />
2. Exercice 2 : mise en place d'une alarme<br />
Nous allons maintenant étudier la gestion d'une alarme par récupération du signal<br />
correspondant. On peut positionner une alarme par la fonction « alarm(secondes) ». Le code<br />
source d'exemple est « test_signal_alarme.cpp ». Il complète le précèdent en ajoutant une<br />
attente d'un événement d'alarme sur un timer réglé à 5 secondes. Si l'utilisateur ne s'est pas<br />
manifesté, le <strong>prog</strong>ramme se termine.<br />
3. Exercice 3 : signaux temps réels<br />
Les 32 autres signaux Linux sont disponible pour l'utilisateur. La valeur minimale de leur rang<br />
est donnée par SIGRTMIN (valeur prédéfinie du système, normalement 34). Un processus gère<br />
une file de signaux reçus (max. <strong>10</strong>24) dans laquelle il prend au fur et à mesure. Les<br />
occurrences sont automatiquement éliminées. On peut attacher au signal quelques<br />
informations, comme le montre l'exemple ci-dessus (entier ou pointeur sur un tableau<br />
d'entiers).<br />
Les prérequis sont : d'avoir 2 processus au moins, de déclarer (pour le receveur) une structure<br />
qui contient les signaux qu'il bloque (sigemptyset, sigaddset), une structure pour récupérer les<br />
informations (struct siginfo infos_recues), un masquage des signaux courants pour filtrer ceux<br />
qui l'intéresse (sigprocmask) et d'attendre (sigwaitinfo, bloquant). Pour l'émetteur, il suffit<br />
d'empaqueter les informations dans une structure et de les placer dans la file des messages du<br />
receveur (sigqueue).<br />
Exemple de code pour envoyer des signaux temps réels d'un processus à un autre (cf .<br />
« test_signal_tempsreel_perefils.cpp ») :<br />
● le père utilise « sigqueue() » pour envoyer un message :<br />
int execution_pere(const unsigned int _pid_fils) {<br />
//une structure pour contenir des informations à envoyer par le message<br />
union sigval infos_envoyees;<br />
//on stocke dans la structure infos_envoyees la valeur <strong>10</strong><br />
infos_envoyees.sival_int = <strong>10</strong>;<br />
std::cout
Iut Arles / A1SE<br />
Systèmes d’exploitation<br />
4. Exercice 4 : et pour finir<br />
Utiliser les signaux temps-réels pour faire passer un pointeur sur un tableau d'entiers<br />
d'une processus à un autre. Pour vous aider, allez faire un tour du côté de la structure<br />
« union sigval », il y a un champ « .sival_ptr ». Il faut déjà déclarer et remplir ce<br />
tableau dans le « main() » car vous n'avez pas encore vu la mémoire partagée.<br />
Attention cette dernière question prend un peu de temps, faites-la plutôt chez vous en<br />
entraînement.<br />
R Raffin, W. Famy & A. François p. 3/3