Systèmes et Réseaux (SR1)
- MIAGE 2
Systèmes d'exploitation
TP n°2 : Signaux
Commande de compilation d'un programme C : gcc -o prog prog1.c prog2.c ... progn.c
Librairie à utiliser (inclure csapp.h aux programmes du TP) : csapp.h et csapp.c
Pour utiliser csapp, ajouter les options suivantes dans la commande de compilation : -l socket -lnsl -lrt
La primitive unsigned int
sleep(unsigned int t) suspend le processus appelant pendant
t secondes ou jusqu'à l'arrivée d'un signal.
Dans ce dernier cas, elle renvoie le nombre de secondes qui restaient à
attendre.
Ecrire un programme qui suspend le processus pendant un nombre de secondes
passées en paramètre, et imprime le nombre de secondes effectivement passées à
attendre, le programme pouvant être interrompu par control-C.
La primitive unsigned int
alarm(unsigned int t) provoque l'envoi d'un signal SIGALRM au processus
appelant au bout de t secondes.
Ecrire un programme qui ne fait rien (exécute une boucle vide) mais qui reçoit
un signal SIGALRM toutes les secondes et affiche alors un message "bip". A la
réception du 6ème signal, le programme affiche "bye" et se termine.
Ecrire un programme qui, lorsqu'il reçoit un
signal SIGINT, affiche le numéro de ce signal et ne fait rien le reste du temps
(on rappelle que la primitive pause permet à un
processus de se bloquer en attendant l'arrivée d'un signal).
Faire de même avec le signal SIGKILL (primitive kill)
et le signal SIGSTOP (control-Z). Que constatez-vous ?
On considère le programme
counterprob.c. Que fait ce programme ?
Exécutez le programme plusieurs fois ; quelle est la valeur imprimée de la
variable counter ?
Ajouter un sleep dans le programme des fils de counterprob.c, après l'instruction Kill. Exécutez le programme plusieurs fois ; quelle est la valeur imprimée de la variable counter ? Expliquer.
Modifier le programme waitpid1.c pour qu'il ait l'effet suivant :
Chaque processus fils essaye d'écrire dans un emplacement protégé contre l'écriture (par exemple, le segment contenant le programme exécutable main ; utiliser le cast nécessaire pour accéder à main en tant que suite d'octets).
Le père indique la fin anormale des fils en imprimant le numéro de chaque fils et la cause de sa terminaison anormale (numéro du signal).
On rappelle que le waitpid renvoie un entier statut que l'on peut tester pour connaître l'état du processus qui s'est terminé. En particulier :
WIFSIGNALED(statut) renvoie vrai si la fin du processus est due à un signal non traité.
Si
WIFSIGNALED(statut) renvoie vrai, alors
WTERMSIG(statut) renvoie le numéro du signal qui
a causé la terminaison du processus.
Pour les messages d'erreur, voir man psignal.
Lorsqu'un processus crée des fils, il peut attendre leur fin avec la primitive
wait ou waipid.
Néanmoins, il ne peut pas faire de travail utile pendant cette attente. C'est
pourquoi l'on souhaite que le processus père traite la fin de ses fils
uniquement au moment où cette fin est signalée par le signal SIGCHLD.
Dans le programme signal1.c, le père crée
trois fils et traite le signal SIGCHLD envoyé lors de la terminaison. Puis le
père lit quelque chose au clavier et se met en boucle.
Exécutez ce programme, attendre que le père se mette en boucle, le suspendre par
control-Z et vérifier, par ps, que tous
les fils n'ont pas été collectés (il reste un zombi).
Pourquoi reste-t-il un processus fils zombi non collecté par le père ?
Modifier le programme pour corriger cette erreur.