Vous êtes sur la page 1sur 7

Les signaux – la synchronisation

Numéro de session

Intitulé de la session

1

Généralités

2

Les types de signaux

3

Gestion des signaux

- envoi d’un signal

- réception d’un signal

- mise en attente d’un signal

1 Session 1 : Généralités

1.1 Définition

Les signaux sont des interruptions logicielles envoyées aux processus par le système d’exploitation. Un signal peut être ignoré, mais s’il est pris en compte, il déclenche de façon asynchrone l’action qui lui est associée. Dans la pratique, les signaux permettent de « tuer » des processus, d’avertir un processus d’un évènement extérieur (terminaison d’un autre processus, fin d’un délai temporel, …) et permettent de ce fait à plusieurs processus de communiquer entre eux. La liste des signaux disponibles sur une machine Unix est disponible dans le fichier suivant :

/usr/include/sys/signal.h Les signaux sont identifiés par le système par un numéro allant de 1 à 31. Pour chaque signal, un mnémonique a été défini en tant que constante afin de mieux préciser son rôle.

Exemple : Mnémonique (numéro associé). SIGINT : (2) est le signal reçu par un processus lorsque l’on exécute un « Ctrl + C ». SIGKILL : (9) est le signal reçu par un processus lorsque l’on exécute un kill -9. Ce signal ne peut être ni ignoré, ni dérouté, on dit qu’il est non masquable.

La liste des signaux avec leur mnémonique peut être obtenue par man 5 signal.

1.2 Implémentation

L’implémentation des signaux Unix est différente selon les systèmes, et pour un même

système selon les plateformes. Par exemple, le signal SIGSTOP peut correspondre aux valeurs suivantes :

- 24 pour HP-UX sur plateforme PA-RISC,

- 19 pour Linux sur i386,

- 17 pour Linux sur Sparc,

- 23 pour Linux sur MIPS.

D’où l’intérêt d’utiliser des symboles plutôt que des numéros.

1.3 Comportement

Le comportement par défaut est l’abandon pour la plupart des signaux, sauf pour :

- SIGQUIT (« Ctrl + \ »), SIGABRT (abandon programmé), SIGFPE (débordement

flottant), SIGSEGV (adresse mémoire invalide) qui provoquent en plus la création d’un fichier d’extension .core.

Un fichier .core contient des informations qui décrivent l’état du processus lors d’une terminaison anormale : état de la mémoire, de la pile, des variables

- SIGSTOP qui fait passer le processus dans l’état suspendu, on le refait passer dans l’état activable par le signal SIGCONT.

- SIGCHLD qui est le signal envoyé par un fils vers son père lorsque le fils reçoit lui- même un signal (notification au père) ou lorsqu’il se termine ; par défaut, ce signal est ignoré.

Un signal est donc une interruption logicielle exploitable par un programme, qui informe un processus de l’occurrence d’un évènement asynchrone. De manière générale on utilise les signaux pour synchroniser des processus.

2

Session 2 : Les types de signaux

Il existe 3 différents types de signaux prédéfinis sous Unix :

2.1 Signaux relatifs à des erreurs internes

sous Unix : 2.1 Signaux relatifs à des erreurs internes envoi d'un signal Le noyau envoi

envoi d'un signal

Le noyau envoi un signal à 1 processus.

Exemple :

SIGSYS (12) : signal émis en cas d'erreur de paramètre dans un appel système.

2.2 Signaux relatifs à des manipulations utilisateur au niveau Shell

relatifs à des manipulations utilisateur au niveau Shell envoi d'un signal par l'intermédiaire du noyau Un

envoi d'un signal par l'intermédiaire du noyau

Un processus émet un signal vers le noyau qui le redirige sur d’autres processus.

Exemple :

SIGINT (2) : signal d'interruption émis à tous les processus associés à un terminal lorsque le caractère d'interruption (en général « Ctrl + C ») est tapé. SIGQUIT (3) : signal d'interruption émis à tous les processus associés à un terminal lorsque le caractère pour quitter une application (en général « Ctrl + \ ») est tapé. SIGKILL (9) : signal de terminaison du processus, permet de tuer un processus quelque soit son état.

2.3 Signaux relatifs à la mise au point de programmes manipulant plusieurs processus

envoi d'un signal entre processus Le processus A doit envoyé un signal au processus B.

envoi d'un signal entre processus

Le processus A doit envoyé un signal au processus B. Le

d’intermédiaire.

noyau joue alors le rôle

Exemple :

SIGUSR1 (16) et SIGUSR2 (17) : signaux utilisateurs utilisés par les programmeurs. SIGALRM (14) : signal associé à une horloge.

2.4

Exemple PRISE ENREGISTRE SIGUSR1 SIGUSR2
Exemple
PRISE
ENREGISTRE
SIGUSR1
SIGUSR2

Prend une vue et la range dans le buffer.

- Prise de vue

- Envoie SIGUSR1 à ENREGISTRE

- Interprète SIGUSR2 :

enregistrement effectué

Stocke l’image sur un support magnétique.

- Interprète SIGUSR1 : la vue a été prise

- Stocke l’image sur support

- Envoi à PRISE que le travail est effectué : SIGUSR2

3

Session 3 : Gestion des signaux

La liste de tous les signaux peut être obtenue par:

- une commande : man 7 signal

- la lecture du fichier : /usr/include/sys/signal.h

3.1 Emission des signaux

Syntaxe :

int kill (pid, sig) int pid, /* identificateur de processus destinataire.*/ int sig; /* identification (numéro) du signal émis.*/

Cette commande permet d’envoyer un signal sig au processus identifié par pid.

Valeur de retour :

- = 0 si succès.

- = -1 si échec.

La variable errno (variable globale qui contient le numéro de la dernière erreur ayant eu lieu)

est positionnée :

- EINVAL : le signal sig n’existe pas, le processus pid n’existe pas.

- ESRCH : mauvais processus cible.

- EPERM : les processus émetteur et récepteur ne sont pas dans la même famille.

Variantes d’utilisation de la fonction kill :

- Si pid > 0 et sig = 0, la fonction kill teste l’existence du processus désigné par pid. Exemple : kill (1234,0) ; Si la valeur de retour est nulle, le processus 1234 existe. Si la valeur de retour est différente de 0, le processus 1234 n’existe pas.

- Si le pid = -1, le signal est envoyé à tous les processus de l’utilisateur.

Exemple : kill (-1, 9) ; Tous les processus de l’utilisateur qui exécute cette commande sont arrêtés.

3.2 Traitement des signaux

Syntaxe :

Int *signal (sig, fcn( )) Int sig , /*numéro de signal à récupérer*/ Int (*fcn()) ; /*pointeur sur la fonction à exécuter lors de la réception du signal*/

Cette commande permet de préciser la fonction à exécuter (fcn()) en mode asynchrone lors de la/des prochaines réceptions du signal précisé (sig). Elle retourne un pointeur vers la fonction précédemment associée au signal. On appelle la primitive signal () dans 3 cas :

- pour prendre en compte (dérouter) le signal avec (vers) une fonction de traitement, c’est un déroutement dans le processus,

- Pour rétablir le comportement par défaut du signal,

- Pour ignorer le signal.

Valeur de retour :

- = 0 si succès,

- = -1 si échec.

La variable errno est positionnée à EINVAL si le signal sig n’existe pas.

Systématiquement, quand un processus reçoit un signal, il fait un traitement particulier. Si la réception de ce signal n’était pas prévue, le traitement est prédéfini par le système. Il s’agit souvent de la terminaison du processus. Pour chaque signal, une terminaison par défaut est prévue.

Exécution d’un traitement particulier :

Fct() est le nom d’une fonction qui est exécutée à la réception du signal.

fonction qui est exécutée à la réception du signal. reception d'un signal et traitement L’avis de

reception d'un signal et traitement

L’avis de récupération d’un évènement spécifié dans la primitive signal() n’est valide que pour une seule occurrence de l’évènement (une seule réception du kill()).

Variantes d’utilisation de la fonction signal :

- Exécution du traitement par défaut (SIGDFL) signal (SIGUSR2, SIGDFL) ;

- Ignorer le signal signal (SIGUSR1, SIGIGN) ;

3.3 Attendre la réception d’un signal

Syntaxe : Int pause ( ) ;

Cette primitive permet de suspendre le processus jusqu’à la prochaine réception d’un signal. Ceci permet d’éviter d’attendre l’arrivée du signal avec une boucle infinie, ce qui consommerait de la ressource UC alors que le processus suspendu n’en consomme pas. La valeur de retour est toujours égale à -1.

Ce chapitre a présenté les caractéristiques générales des signaux ainsi que les méthodes qui permettent leur utilisation : kill(), signal(), et pause(). Nous avons ainsi pu voir que les signaux sont des moyens de synchronisation de processus. Nous verrons dans le chapitre suivant que des processus peuvent communiquer entre eux grâce aux tubes (pipes).