Lorsque vous développez une application, il est parfois très intéressant d’utiliser des threads ou plusieurs processus pour exécuter plusieurs tâches simultanément. Nous allons ici voir un problème qui arrive lors que l’on utilise plusieurs processus, via un fork(). En effet, en C, la fonction fork permet de créer un nouveau processus, qui devient fils du processus appelant le fork.
Processus zombies (defunct)
Par défaut, lorsque le processus père s’arrête, tous les processus fils s’arrête. À l’inverse, lorsqu’un processus fils s’arrête – via un exit(0); par exemple -, sa mémoire est libérée, il devient un processus zombie (seul le bloc de contrôle reste présent) et le processus père continue de fonctionner.
Ainsi, l’on peut voir de nombreuses lignes marquées par un defunct lorsque l’on liste les processus avec un ps:
root 9175 0.0 0.0 136380 1100 ? Sl Jun30 0:00 /[...]/relay root 9629 0.0 0.0 0 0 ? Z Jun23 0:00 [relay] <defunct> root 9853 0.0 0.0 0 0 ? Z Jun30 0:00 [relay] <defunct> root 9884 0.0 0.0 0 0 ? Z Jun30 0:00 [relay] <defunct>
C’est parce que le processus père n’écoutes pas le signal SIGCHLD, qui est envoyé par le fils lors de son extinction. Ainsi, en écoutant le signal, le père peut libérer son bloc de contrôle. En C, c’est la fonction waitpid qui nous sera utile.
Une ligne à ajouter
Il n’y a qu’une seule ligne (ainsi qu’un #include) à ajouter à votre code C pour que les processus zombies soient “ramassés” par votre processus père. De temps en temps – l’idéal étant la boucle principale s’il y a -, exécutée cette ligne ci:
while (waitpid(WAIT_ANY, NULL, WNOHANG) != 0);
Les arguments sont les suivants:
WAIT_ANYest la constante permettant de dire que l’on souhaite attendre n’importe quel des processus fils de ce processus. À la place, nous aurions pu mettre le pid d’un processus particulier.NULLpermet de ne pas récupérer d’informations de statut du processus.WNOHANGest une option permettant d’exécuterwaitpiden mode non-bloquant.
N’oubliez pas d’inclure l’en-tête des fonctions et constantes ainsi:
#include <sys/wait.h>Ainsi, il ne restera plus de processus zombie, ou defunct.
Je vous invite donc à tester dès à présent MyOnlineSSH: