Questions à choix multiples¶
Question 1. Signaux synchrones et asynchrones¶
Un signal est dit synchrone lorsqu’il est causé par l’exécution d’une instruction du processus. Un signal est dit asynchrone s’il n’a pas été causé directement par l’exécution d’un instruction du processus.
- Le signal SIGFPE est synchrone.
- Le signal SIGSEGV est synchrone.
- Le signal SIGALRM est asynchrone.
- Le signal SIGCHLD est synchrone.
- Le signal SIGINT est synchrone.
- Le signal SIGTERM est synchrone.
- Le signal SIGBUS est synchrone.
Question 2. Signaux pour arrêter un processus¶
- Envoyer un signal SIGKILL à un processus le termine toujours immédiatement.
- Lorsque l’on tappe Ctrl-C dans le shell pendant l’exécution d’un programme, un signal SIGINT est envoyé au processus en cours d’exécution.
- Envoyer un signal SIGTERM ou SIGINT est préférable à SIGKILL car le processus peut prévoir une routine de traitement de signal pour se terminer proprement.
- Envoyer un signal SIGTERM à un processus le termine toujours immédiatement.
- Lorsque l’on tappe Ctrl-C dans le shell pendant l’exécution d’un programme, un signal SIGTERM est envoyé au processus en cours d’exécution.
- Envoyer un signal SIGTERM ou SIGKILL est préférable à SIGTERM car le processus peut prévoir une routine de traitement de signal pour se terminer proprement.
Question 3. Routines de traitement de signal¶
Un étudiant a décidé d’implémenter un programme simulant une bombe à retardement qui détonne 1h après son intialisation. Pour accélérer le décompte, l’étudiant a enregistré un handler pour le signal SIGUSR1 qui divise par 2 le temps restant à décompter.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int counter = 3600;
void counter_boost(int signum) {
counter=counter/2;
printf("Boost!\n");
}
int main () {
if (signal(SIGUSR1,counter_boost)==SIG_ERR) {
perror("signal");
exit(EXIT_FAILURE);
}
while(counter>0) {
counter--;
printf("%d seconds left\n", counter);
sleep(1);
}
printf("BOOM!");
return(EXIT_SUCCESS);
}
- Il y a un risque que la variable counter soit accédée en même temps par le processus et la routine de traitement de signal. Il est nécessaire de la déclarer sig_atomic_t pour résoudre ce problème.
- La fonction printf(3) n’est pas réentrante et ne doit pas être utilisée dans une routine de traitement de signal.
- Il y a un risque que la variable counter soit accédée en même temps par le processus et la routine de traitement de signal. Il est nécessaire de protéger cette variable par un mutex.
- Il y a un risque que la variable counter soit accédée en même temps par le processus et la routine de traitement de signal. Il est nécessaire de la déclarer volatile pour résoudre ce problème.
- Il est interdit de modifier une variable globale (telle que counter) dans une routine de traitement de signal.
Question 4. Implémentation des signaux sous Unix¶
Deux stratégies existent pour implémenter les signaux sous Unix: maintenir une queue de tous les signaux destinés à un processus donné ou représenter l’ensemble des signaux qu’un processus peut recevoir sous la forme de drapeaux binaires (un par signal). Linux utilise la seconde stratégie.
- La solution sous forme de queue sans limite de taille permet de s’assurer que tout signal envoyé au processus est reçu par le processus.
- La solution sous forme de drapeaux binaires ne nécessite qu’un seul bit de mémoire par signal mais n’est pas forcément meilleure que la solution utilisant une queue.
- La solution utilisant une queue permet de s’assurer que tout signal envoyé au processus est reçu par le processus. Elle est donc meilleure que la solution sous forme de drapeaux binaires.
- Une solution intermédiaire utilisant 10 drapeaux par type de signal permettrait d’être à la fois fiable et économe en mémoire.
- La solution utilisant des drapeaux binaires permet de s’assurer que tout signal envoyé au processus est reçu par le processus.
- Avec la solution utilisant des drapeaux binaires, seul les signaux envoyés plusieurs fois avant l’exécution routine de traitement de signal seront perdus.