PROGRAMMATION SYSTEME Léon Mugwaneza (email: mugwaneza@univmed.fr) 2: SIGNAUX 1
SIGNAUX Notification logicielle émise par un processus ou par le noyau qui oblige le processus destinataire à prendre immédiatement (aux délais dus à l ordonnancement près) une mesure spécifique (traiter le signal) Un mécanisme de communication/synchronisation entre processus : une primitive d appel système permet à un processus d envoyer un signal à un ou plusieurs processus (appel système kill) Une commande permet à l utilisateur d envoyer un signal à un ou plusieurs processus (commande kill) Les signaux émis par le noyau correspondent à des conditions logicielles ou matérielles particulières : caractères de contrôle tapées au clavier (ex: CTR-C) erreur dans le programme (violation de protection mémoire, erreur d E/S, ) terminaison d un processus fils 2
TRAITEMENT DES SIGNAUX 3 façons différentes: Les ignorer (eg. CRL- C pour les processus lancés en arrière plan) Exécution du traitement par défaut Exécution d un traitement spécifiée par l utilisateur 3
QUELQUES SIGNAUX POSIX Identifiés par le système par un nombre entier (numéro). - Les numéros associés aux signaux peuvent varier en fonctions des systèmes Quelques exemples (la commande shell kill l donne les noms des divers signaux + les numéros sur certains systèmes) SIGHUP 1 déconnection du terminal SIGINT 2 interruption interactive par l utilisateur (CTL-C) SIGQUIT 3 abandon CTL- (core dump) SIGKILL 9 destruction (ne peut être ignoré, traitement par défaut seul) SIGUSR1 10 réservé à l utilisateur (communication inter-processus) SIGUSR2 12 réservé à l utilisateur (communication inter-processus) SIGPIPE 13 essai d écriture dans un pipe non ouvert en lecture SIGALRM 14 Alarme (délai spécifié par le processus écoulé -- alarm()) SIGTERM 15 terminaison normale d un processus SIGCHLD 17 mort d un fils (envoyé au père) etc voir fichier /usr/include/asm/signal.h (dépend du SE) /usr/include/asm-i486/signal.h (SE debian) 4
Appel système pour envoyer un signal : kill L appel système kill() permet d envoyer un signal à un ou +eurs processus #include<signal.h> int kill(int pid, int no_signal) ; no_signal est le numéro du signal (les macros définies dans le fichier enête signal.h permettent d utiliser un nom symbolique) pid no du processus récepteur si pid==0 tous les processus du groupe sont concernés l envoi de signal ne peut se faire qu entre processus de même UID (appartenant au même utilisateur) résultat 0 si le signal a été envoyé -1 sinon (erreur) exemple : res = kill(0, SIGUSR1); 5
Traitement des signaux: signal (1) L appel système signal() permet de spécifier le comportement d un processus à la réception d un signal #include <signal.h> void (*signal (int sig, void (*fcn)(int)))(int) - sig : numéro du signal - (*fcn) : traitement à exécuter à la réception (on exécute fcn(sig), ou le traitement par défaut, ou le signal est ignoré) - retourne l action précédente ou SIG_ERR Effet : installe (attache) fcn comme traitant du signal sig (fcn devient fonction attachée au signal sig, fcn peut être SIG_DFL ou SIG_IGN) 6
Traitement des signaux: signal (2) Prototype plus lisible en utilisant typedef #include <signal.h> typedef void (* sig_t) (int); sig_t signal(int sig, sig_t fcn); Exemples: sig_t res ; res= signal(sigusr1, traitant) ; res= signal(sigint, SIG_IGN); 7
Effet de la réception d un signal (1) Dépend du traitement attaché au signal (SE ou appel système signal() ) SIG_DFL ==> action par défaut propre à chaque signal et prédéterminé par le SE souvent terminaison du processus (abnormal termination) SIG_IGN ==> pas d action, le signal est ignoré certains signaux ne peuvent pas être ignorés Fonction attachée ==> action spécifiée par la fonction 8
Effet de la réception d un signal (2) A la réception du signal, si le signal n est pas ignoré : l exécution cours est interrompu la fonction attachée ou le traitement par défaut est exécuté l exécution du processus reprend son cours le traitement par défaut peut conduire à la terminaison du processus 9
kill et signal : exemple #include <signal.h> #include <assert.h> int main(void) { int pid ; pid=fork(); assert(pid>=0); if(pid == 0) execv(" fils ", NULL); signal(sigusr1,fonc) ; for(;;) { printf(" je boucle\n "); sleep(1); } } void fonc(int sig) { printf(" signal recu %d\n ", sig); exit(0); } // l exécutable s appelera fils #include <signal.h> int main(void) { sleep(5); kill(getppid(),sigusr1); exit(0); } le fils envoie le signal SIGUSR1 au père. Le père arrêtera la boucle et exécutera fonc (et terminera) 10
Appel système d attente d un signal : pause Syntaxe : #include <unistd.h> int pause(void); Effet : met le processus appelant en attente de l arrivée d un signal quelconque après l exécution du traitement attaché au signal reçu retourne -1 et errno = EINTR 11
Appel système d émission d un signal après un délai donné : alarm L appel système alarm() envoi le signal SIGALRM au processus appelant après le laps de temps spécifié (en seconde) Syntaxe : #include<unistd.h> int alarm( int sec) ; Effet : - un appel à alarm() avant l arrivée du signal d un précédent appel à alarm() annule le précédent appel - resultat: - temps écoulé depuis le dernier appel - 0 si aucun appel alarm() en cours 12