Qu'est ce qu'un zombie ?

Des processus pas tout à fait morts...

02 juin 2014

Lorsqu'un processus père créé un processus fils, par exemple avec la fonction fork, il a le devoir d'écouter l'état de son fils et de vérifier s'il n'est pas mort grâce aux fonctions wait et waitpid.

Tout processus fils qui meurt et dont le père, toujours en vie, n'est pas au courant, est appelé processus zombie. Ce processus a été totalement désalloué de la mémoire mais reste toutefois présent dans la table des processus. La table des processus étant limitée en taille et chaque zombie occupant l'une des places disponibles, il pourrait devenir impossible de créer de nouveaux processus, ce qui provoquerait un gel du système.

Les OS récents ont tous des sécurités pour éviter ce type de blocage, néanmoins c'est évident qu'il est préférable de ne jamais avoir de zombie. Le nom "zombie" provient du fait que le processus est pratiquement mort mais ne peut pas être tué directement. Pour tuer un zombie il est nécessaire de tuer son père, le zombie est alors automatiquement rattaché au processus n°1 (init) qui s'occupera de le tuer.

Fonctionnement normal avec waitpid

#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main(void)
{
        pid_t pids[1];

        pids[0] = fork();

        if (pids[0] == 0) {
                /* On est dans le processus fils */
                sleep(20);
                _exit(0);
        }
        else{
                printf("Processus courant : %d\n", getpid());
                /* Verification du code retour du fils */
                waitpid(pids[0], NULL, 0);
                printf("Processus fils termine : %d\n", pids[0]);
                sleep(50);
        }

        return 0;
}

/*
 * Sortie :
 *
 * Processus courant : 11793
 * Processus fils termine : 11794
 */

Processus qui tournent

ps aux | grep "zombie"
nico     11793  0.0  0.0   1536   380 pts/0    S+   15:58   0:00 ./zombie
nico     11794  0.0  0.0   1532   156 pts/0    S+   15:58   0:00 ./zombie

Créer un processus zombie

#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main(void)
{
        pid_t pids[1];

        pids[0] = fork();

        if (pids[0] == 0) {
                /* On est dans le processus fils */
                _exit(0);
        }
        else{
                printf("Processus courant : %d\n", getpid());
                printf("Processus fils dont on ne sait pas s'il est termine : %d\n", pids[0]);
                sleep(50);
        }

        return 0;
}

/*
 * Sortie :
 *
 * Processus courant : 11957
 * Processus fils dont on ne sait pas s'il est termine : 11958
 */

Processus zombie : le processus père tourne et ne s'occupe pas de savoir que son processus fils est mort

ps aux | grep "zombie"
nico     11957  0.0  0.1   1536   384 pts/0    S+   16:01   0:00 ./zombie
nico     11958  0.0  0.0      0     0 pts/0    Z+   16:01   0:00 [zombie] <defunct>

Un zombie est facilement reconnaissable car la colonne STAT contient la valeur : z, Z, Z+.

Voici une commande pour les tuer :

Tuer tous les processus zombies

kill -HUP $(ps -A -ostat,ppid | grep -e '[zZ]'| awk '{ print $2 }')

# Pour l'exemple précédent la commande kill le processus 11957

A bientôt !

Par
Créateur et administrateur.

Dans la même catégorie

Qu'est ce qu'un démon ?

Commentaire(s)