Les signaux constituent la forme la plus simple de communication entre processus. Un signal est la notification asynchrone d'un événement. Un signal est dit envoyé au processus quand l'événement associé au signal se produit.
Il y a plusieurs types de signaux, indiquant chacun une condition particulière. Les signaux reçus par un programme proviennent de plusieurs sources possibles:
L'utilisateur, au clavier. Par exemple, le driver de terminal envoie le signal sigint à tous les processus lancés depuis ce terminal (qui n'ont pas été mis en arrière plan) quand l'utilisateur tape le caractère d'interruption ctrl-C. De même, il envoie sigquit quand l'utilisateur tape ctrl-\. Et il envoie sighup lorsque la connexion avec le terminal est fermée, ou bien parce que l'utilisateur s'est déconnecté.
L'utilisateur, par la commande kill. Cette commande permet d'envoyer un signal quelconque à un processus quelconque. Par exemple, kill -KILL 194 envoie le signal sigkill au processus 194, ce qui a pour effet de terminer à coup sûr ce processus.
D'un autre programme (via le système) qui exécute un appel système kill (le cas précédent en étant un cas particulier).
Le système, pour des processus qui se comportent mal. Par exemple, un processus qui effectue une division par zéro reçoit un signal sigfpe.
Le système, pour prévenir un processus que son environnement a changé. Par exemple, lorsqu'un processus meurt, son père reçoit le signal sigchld.
Le but de ce TP est d'étudier les signaux et les processus (en langage C).
Exercice 1 - Masquer des signaux
Écrire un processus qui masque les signaux SIGINT et SIGQUIT pendant 10 secondes puis rétablit le traitement par défaut de ces signaux.
Écrire un processus qui ignore les cinq premiers signaux SIGINT et réagit au sixième : il intercepte les cinq premiers sans faire de traitement particulier puis sur le sixième, il rétablit le handler SIG_DFL.
Écrire un programme C qui compte les signaux qu'il reçoit et affiche ces compteurs.
Exercice 2 - Synchronisation entre processus
Écrire un programme C qui crée deux processus à l'aide de l'appel système fork(). Le père affichera les entiers pairs compris entre 1 et 100, le fils affichera les entiers impairs compris dans le même intervalle. Synchroniser les processus à l'aide des signaux pour que l'affichage soit 1 2 3 ... 100.
topExercice 3 - Signal SIGALARM
Écrire un programme qui propose à l'utilisateur un calcul sur 3 entiers tirés pseudo-aléatoirement en contrôlant son temps de réponse :
si l'utilisateur ne répond pas au bout d'un temps t fixé, le programme se termine avec un message d'avertissement.
sinon le programme propose un autre calcul
Écrire un programme qui affiche l’heure chaque minute puis le message Dring à une heure donnée par l’utilisateur.
Exercice 4 - Sac à dos
Faire un programme C qui fabrique une instance aléatoire du problème du "sac à dos" modulo 232 et qui cherche à la résoudre par recherche exhaustive.
Le programme engrendre donc dans un premier temps 33 nombres s, p1, ..., p32 de 32 bits de manière pseudo-aléatoire.
Une solution du problème est un sous-ensemble I de {1,...,32} tel que la somme modulo 232 des pi pour i dans I est égale à s.
Une telle recherche est assez longue. On cherche à pouvoir la lancer en arrière plan, tout en pouvant continuer à dialoguer avec le processus. On cherche essentiellement à lui transmettre plusieurs messages différents:
- afficher ou la recherche en est (message STATUS),
- abandonner la recherche et recommencer avec une autre instance (message RESTART),
- abandonner définitivement (message STOP),
- demander l'affichage des sous-ensembles I qui seraient des solutions modulo 2n (message DISP n).
Définir un protocole de signaux pour coder ces messages, et faire une application C qui envoie ce type de message à un processus donné.
topPour mémoire, voici un extrait du fichier signal.h :
#define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt (rubout) */ #define SIGQUIT 3 /* quit (ASCII FS) */ #define SIGILL 4 /* illegal instruction (not reset when caught)*/ #define SIGTRAP 5 /* trace trap (not reset when caught) */ #define SIGIOT 6 /* IOT instruction */ #define SIGABRT 6 /*used by abort, replace SIGIOT in the future */ #define SIGEMT 7 /* EMT instruction */ #define SIGFPE 8 /* floating point exception */ #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10 /* bus error */ #define SIGSEGV 11 /* segmentation violation */ #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ #define SIGUSR1 16 /* user defined signal 1 */ #define SIGUSR2 17 /* user defined signal 2 */ #define SIGCLD 18 /* child status change */ #define SIGCHLD 18 /* child status change alias (POSIX) */ #define SIGPWR 19 /* power-fail restart */ #define SIGWINCH 20 /* window size change */ #define SIGURG 21 /* urgent socket condition */ #define SIGPOLL 22 /* pollable event occured */ #define SIGIO SIGPOLL /* socket I/O possible (SIGPOLL alias) */ #define SIGSTOP 23 /* stop (cannot be caught or ignored) */ #define SIGTSTP 24 /* user stop requested from tty */ #define SIGCONT 25 /* stopped process has been continued */ #define SIGTTIN 26 /* background tty read attempted */ #define SIGTTOU 27 /* background tty write attempted */ #define SIGVTALRM 28/* virtual timer expired */ #define SIGPROF 29 /* profiling timer expired */ #define SIGXCPU 30 /* exceeded cpu limit */ #define SIGXFSZ 31 /* exceeded file size limit */ #define SIGWAITING 32 /* process's lwps are blocked */ #define SIGLWP 33 /* special signal used by thread library */ #define SIGFREEZE 34/* special signal used by CPR */ #define SIGTHAW 35 /* special signal used by CPR */ #define SIGCANCEL 36/*thread cancel signal used by libthread */ #define _SIGRTMIN 37/*first (highest-priority) realtime signal*/ #define _SIGRTMAX 44/* last (lowest-priority) realtime signal */