TD 3 : Processus - Création et Synchronisation

Introduction      FAQ   TD 1   TD 2   TD 3   TD 4   TD 5   TD 6   TD 7   TD 8

1.  Passage en mode service (go_daemon)

Le serveur est un service Unix, qui doit s'exécuter indépendemment du terminal et du processus qui a servi à le lancer. Transformer un processus standard en service s'effectue généralement en créant un premier fils, en démarrant une nouvelle session dans ce fils, puis en créant un petit-fils dans cette session: le père et le fils peuvent terminer immédiatement, tandis que le petit-fils continue, indépendemment de la session de départ et du processus père.

Pour cela, le serveur utilise une fonction go_daemon(),

extern void go_daemon ();

qu'il exécute à la fin de son démarrage dans main(). Cette fonction effectue le passage en service, termine le père et le fils, laissant seul le petit-fils poursuivre l'exécution.

Cette fonction est actuellement fournie par la librairie libforumserver.a. Implantez votre propre version de cette fonction dans le fichier server.c.

Fonctions à utiliser (man): fork, exit, setsid

Solution: go_daemon.c

Existe t'il des outils pour voir quels processus s'exécutent ?

L'outil le plus connu pour lister les processus est ps :

ps

qui liste les processus de l'utilisateur et de la session courante :

   
PID TTY          TIME CMD
19108 pts/1    00:00:00 tcsh
19590 pts/1    00:00:00 ps

Pour avoir plus de processus, il faut fournir quelques options :

ps -ef

ou pour être plus verbeux (ligne de commande complète) :

ps -efww

Enfin, il existe bien d'autres utilitaires:

top

affiche uniquement les processus qui consomment le plus de temps machine, et maintient cet affichage à jour.

pstree

affiche les relations entre les processus dans le système.

 strace -p 19108 

permet enfin de tracer un processus déjà en cours d'exécution partir de son numéro.

2.  Appel de l'éditeur (call_editor)

Pour poster un article, le client doit permettre à l'utilisateur d'entrer son contenu. Pour améliorer la convivialité de notre forum, nous utilions pour cela un éditeur extérieur. Le nom de la commande à utiliser est stocké dans la variable d'environnement EDITOR. Si celle-ci est vide, le client utilise la valeur par défaut de la macro EDITOR de forum.h.

Pour appeler l'éditeur, le client utilise une fonction call_editor(),

extern FILE* call_editor ();

qui lance l'éditeur, en lui fournissant le nom d'un fichier temporaire à remplir, attend que l'éditeur se termine, puis ouvre un descripteur de type FILE* dessus pour que le client puisse lire son contenu.

Cette fonction est actuellement fournie par la librairie libforumclient.a. Implantez votre propre version de cette fonction dans le fichier client.c.

Fonctions à utiliser (man): mkstemp, getenv, fork, execlp, wait.

Solution: call_editor.c

3.  Verrou Persistant (program_lock)

Dans le TD1, nous avions écrit une fonction program_lock pour empécher notre programme de démarrer si le même programme était déjà en cours d'exécution. Cette fonction était rudimentaire, puisqu'elle se contentait de créer un fichier vide.

Nous proposons d'améliorer le fonctionnement de cette fonction, en détectant les cas où le programme n'a pas pu quitter correctement, et a laissé un fichier persistant empêchant le démarrage d'autres programmes.

Que sont les signaux ?

Les signaux sont des messages rudimentaires qui peuvent être utilisés pour communiquer une information à un processus. L'information est minimale, puisqu'un signal ne contient que son numéro. Celui-ci porte heureusement un nom symbolique, en fonction de son utilisation: SIGINT (quand l'utilisateur tape Ctrl-C, ce signal est envoyé au processus), SIGKILL (signal tuant le processus sans recours), etc... La liste des signaux disponibles peut être trouvée avec:

man 7 signal

Pour envoyer un signal à un processus, il faut utiliser l'appel système kill. Pour tester, il est aussi possible d'utiliser les commandes kill et killall. Par exemple:

killall -INT client

envoie le signal KILLINT à tous les processus correspondant à la commande client.

Enfin, il est aussi possible de tester l'existance d'un processus en lui envoyant le signal 0, l'appel système retournant une erreur si le processus n'existe pas, sans que le signal soit envoyé au final.

Pour cela, nous proposons de modifier la fonction program_lock pour, d'une part, sauver le numéro du processus dans le fichier et, d'autre part, lorsqu'un tel fichier est trouvé, verifier que le processus est toujours vivant, grâce à l'appel système kill.

Fonctions à utiliser (man): kill.

On remarque par ailleurs que le numéro de processus sauvegardé par program_lock n'est plus le bon. Que faut-il faire ?