Synchronisation des processus père - fils Les signaux
Signaux : terminaison d’un processus Un processus termine à sa demande ou suite à l ’occurrence d’un événement La terminaison implique : la libération des ressources (mémoire, verrous..) ; la fermeture des fichiers ; le signalement de l’événement aux fils (SIGHUP), en cas de fin de session ; le rattachement des processus fils (orphelins) à l’init l ’information du père (SIGCHLD) ; sauvegarde du code de retour et passage à l ’état zombi
Demande de terminaison instruction return(valeur) --> retour au lanceur fonction standard de la bibliothèque C exit(), qui vérifie la copie des tampons #include <stdlib.h> void exit (int valeur) primitive du système _exit() (utilisée par exit()) #include <unistd.h> void _exit (int valeur) Remarque : exit() est préférable à _exit() car elle vide les buffers.
Code de retour Le shell le stocke dans une variable (? Pour sh; status pour csh) Que se passe-t-il si le père termine avant le fils ?
Status ? Fork() Fork() père père fils fils init status init status Père se termine avant le fils n= pid du père m=1 (pid de l ’init) n=getppid() SIGCHLD SIGHUP init m=getppid() status init status Fils se termine avant le père
Synchronisation père-fils fork() wait() zombi fils execl() programme exit() recouvrement Exemple : exécution d’une commande dans sh : ps (pas de wait pour une commande lancée en arrière plan)
Primitive waitpid sélection d’un fils particulier ou un groupe de processus Syntaxe : pid_t wait(pid_t pid, int *ptr_status, int options); valeur de retour : -1 : erreur (pas de fils) 0 : echec >0 pid d’un fils zombi s ’il en existe un. sélection d’un fils : -1 : tous les fils 0 : tous les fils du groupe de l ’appelant >0 pid ayant cette identité. options : 0 : bloquant 1 : non bloquant (constante WNHANG dans wait.h) - s’il n’existe pas de fils ayant terminé, échec, waitpid retourne « 0 »; sinon retourne le pid du fils terminé ou -1.
Signaux Signal : moyen d’indiquer un événement ou de synchroniser des processus Evénements : extérieur au processus : terminaison d’un fils, occurrence d’une interruption (^C par exemple), etc. intérieur au processus en cas d’erreurs : instruction illégale, violation de segment , etc. Synchronisation : primitive : int kill(pid_t pid, int sig) kill -signum pid si pid >0, signal envoyé au processus de ce pid si pid = 0, signal envoyé à tous les processus du groupe de l ’appelant
Principaux signaux (kill -l pour avoir la liste complète ou signal.h) Evénement Effet N° Nom 1 SIGHUP Fin de session Terminaison 2 SIGINT Caractère d’interruption frappé Terminaison 3 SIGQUIT Caractère quit Core dumped 4 SIGILL Instruction illégale Core dumped 8 SIGFPE Expr. arithmétique (v.flottante) Core dumped 9 SIGKILL Terminaison Terminaison 11 SIGSEGV Violation mémoire Core dumped SIGPIPE Ecriture dans tube sans lecteur Terminaison 13 14 SIGALARM Alarme d’horloge Terminaison
Principaux signaux (kill -l pour avoir la liste complète ou signal.h) Evénement Effet N° Nom 16 SIGUSR1 Signal 1 pour les utilisateurs Terminaison 17 SIGUSR2 Signal 2 pour les utilisateurs Terminaison 18 SIGCHLD Terminaison d ’un fils Ignorer 23 SIGSTOP Demande de suspension Suspension 25 SIGCONT Demande de reprise (pour un processus suspendu) Ignorer Remarque : les N° ne sont pas standards. Pour la portabilité, il vaut mieux utiliser les noms symboliques
Traitement d’un signal A chaque type de signal est associé un handler par défaut défini dans SIG_DFL. Plusieurs signaux peuvent utiliser le même handler. Par exemple, pour terminer un processus, le même handler peut être utilisé par les signaux 1, 2, 9, 13.. Signal ignoré : on associe au signal un handler vide : SIG_IGN ce handler vide est exécuté mais n’a pas d’effet. Signal bloqué : aucun handler n’est exécuté. Signal pendant qui attend la modification du masque.
Comportements par défaut SIGHUP SIGINT SIGQUIT SIGFPE SIGKILL SIGSTOP SIGPIPE ... terminer core_dump SIG_IGN suspendre reprendre terminaison terminaison avec copie de l’image mémoire (core dumped) SIG_IGN : ignoré -- SIGCHLD dans la plupart des versions suspension : arrêt du processus (SIGSTOP, SIGTSTP) reprise d ’un processus suspendu (SIGCONT) SIGKILL, SIGSTOP, SIGSTSTP : handlers non modifiables et signaux ne peuvent être bloqués.
Handler Pas de valeur de retour Récupère le numéro du signal comme paramètre Invoqué quelque soit l’endroit du code installation simplifiée avec l’interface signal() void handler (int sig) {………….. } ….. signal (sig, handler) attente d’un signal : int pause(void) ou int sleep(int sec)
Prise en compte d’un signal La réception d’un signal met à 1 le bit du vecteur des signaux pendants Représentation des signaux dans le BCP NSIG 3 2 1 Signaux pendants 0/1 0/1 0/1 0/1 Signaux bloqués ou masqués 0/1 0/1 0/1 0/1 Comportements à la prise en compte
Prise ne compte d’un signal La prise en compte n’est pas instantanée Actif en mode noyau Actif en mode user Handler est exécuté juste avant le passage du mode actif en noyau l ’état actif en mode user. Terminaison éventuelle avant le passage à l’état actif en mode user.
Prise en compte d’un signal Signal reçu par un processus en attente Réception du signal actif en noyau en attente Prêt Pour que le signal soit pris en compte, il faut activer le processus même s’il doit retourner en attente après l’exécution du handler