« Programmation C/Gestion des signaux » : différence entre les versions

Contenu supprimé Contenu ajouté
Déplacement vers Programmation C/Gestion des signaux et reformulation + cat
Ligne 9 :
Les fonctions suivantes, fournies par l'en-tête <tt>signal.h</tt>, sont utilisées dans la gestion des signaux :
* <tt>signal()</tt> pour définir un gestionnaire de signal;
* et <tt>raise()</tt> pour envoyer un signal au processus courant;.
 
* <tt>kill()</tt> pour envoyer un signal à un autre processus (on notera que cette fonction est fournie en extension dans ''Unix System V'' et POSIX, et n'existe pas dans la norme C);
Le C définit ces deux fonctions, et pas plus, alors que les signaux peuvent faire beaucoup plus... En particulier, aucune fonction pour envoyer un signal à un autre processus n'est définie. Cela est dû au fait que, sur certains systèmes, la notion de processus n'existe pas, et une seule tâche s'exécute. Dans de telles situations, il serait aberrant de demander à un compilateur C pour un tel système de fournir des moyens de communications inter-processus ! Par contre, les communications inter-processus étant chose courante dans de nombreux autres systèmes, des extensions fournissent des moyens de le faire (voir par exemple la fonction <tt>kill()</tt> définie dans POSIX, cf. le chapitre [[Programmation POSIX:Signaux|Gestion des signaux]] du livre [[Programmation POSIX]]).
* <tt>pause()</tt> pour attendre un signal (id.).
 
== Définir un gestionnaire de signal ==
Ligne 44 :
En cas d'erreur, la fonction renvoie <tt>SIG_ERR</tt> et place la variable <tt>errno</tt> à une valeur significative.
 
[[Catégorie:Programmation C (livre)]]
== Envoi d'un signal à un autre processus ==
L'en-tête <tt>signal.h</tt> nous fournit la fonction
<source lang="c">
int kill(pid_t pid, int sig);
</source>
Le paramètre <tt>pid</tt> permet d'identifier le ou les processus qui recevront le signal:
*pid > 0 : identifiant d'un processus;
*pid == 0 : le signal sera envoyé à tous les processus du groupe du processus courant;
*pid == -1 : le signal sera envoyé à tous les processus de l'utilisateur. En super-utilisateur (uid=0), tous les processus (sauf système) reçoivent le signal.
 
=== Exemple ===
Par exemple, un processus fils envoie le signal <tt>SIGFPE</tt> a son père qui a pour fonction d'afficher dix fois le message "Pere". Le processus fils enverra le signal <tt>SIGFPE</tt> (''floating point exception'', exception de virgule flottante) :
 
<source lang="c">
#include <stdio.h>
#include <signal.h>
 
int main(void)
{
pid_t pid = fork();
 
if (pid > 0)
{
int iterations = 10;
while (iterations--)
{
puts("Pere");
}
}
else if (pid == 0)
{
puts("Fils");
kill(0, SIGFPE);
}
else
{
puts("Erreur: fork() impossible");
}
return 0;
}
</source>
 
Une sortie possible est:
$ cc exkill.c -o exkill
$ ./exkill
Fils
Floating point exception
 
Ici, le processus père n'a pas eu le temps d'afficher le message avant l'exécution du fils que celui-ci a généré une exception de virgule flottante. Le traitement par défaut de ce signal étant l'arrêt du processus, le père s'est terminé.
 
Il est possible, suivant la manière dont les processus sont synchronisés, que le processus père affiche une ou plusieurs lignes avant d'être interrompu par le signal.