Lorsque vous surveillez un système Linux avec la commande top, il arrive de trouver des éléments dans la ligne 'Tasks' comme 1 zombie.
top - 16:03:19 up 7:09, 1 user, load average: 2.24, 2.21, 2.29
Tasks: 392 total, 1 running, 390 sleeping, 0 stopped, 1 zombie
...
Que signifie ce 'zombie' et quel impact cela a-t-il sur le système ? Dans cet article, nous allons expliquer clairement ce qu'est un processus zombie et comment l'identifier et le résoudre.
Qu'est-ce qu'un processus zombie ? 🧟
Pour comprendre facilement, comparons-le au cycle de vie d'un processus.
-
naissance (Fork) : Le processus parent crée un processus enfant (
fork()). -
exécution (Exec) : Le processus enfant exécute son travail.
-
fin (Exit) : Le processus enfant termine son travail et se termine (
exit()). -
récolte (Wait) : Lorsque le processus enfant se termine, le système d'exploitation (noyau) laisse des informations comme le PID du processus et son état de terminaison dans la table des processus. Ensuite, il envoie un signal
SIGCHLD(le processus enfant s'est terminé) au processus parent. -
Le processus parent doit recevoir ce signal et appeler le système d'appel
wait()pour "récolter" les informations sur l'état de terminaison de l'enfant. Une fois que ces informations sont récoltées, le noyau peut enfin supprimer complètement l'entrée de l'enfant de la table des processus.
Un processus zombie est un processus coincé entre l'étape 4 et 5. En d'autres termes, le processus enfant a terminé son exécution et s'est arrêté, mais le processus parent n'a pas encore appelé wait() pour récolter l'état de terminaison.
Comme son nom l'indique, ce processus est dans un état mort (non en cours d'exécution). Par conséquent, il n'consume pas de ressources système comme le CPU ou la mémoire.
Pourquoi un processus zombie pose-t-il problème ?
Un processus zombie lui-même utilise peu de ressources système, mais il occupe une case du tableau des processus (PID).
Si des bogues dans le processus parent empêchent le nettoyage des processus zombies, le système peut atteindre la limite supérieure du nombre de PID qu'il peut allouer. Dans ce cas, le système ne pourra plus créer de nouveaux processus, ce qui peut entraîner une panne grave. Il n'est pas rare de voir 1 ou 2 zombies dans top, mais si ce nombre continue d'augmenter, il est nécessaire d'agir.
Comment vérifier et identifier un processus zombie
La commande top ne montre que le _nombre_ de zombies. Pour savoir quel processus est en état de zombie et quel est son parent, vous devez utiliser la commande ps.
Le moyen le plus simple consiste à rechercher les processus marqués par 'Z' dans la colonne STAT de la commande ps.
# Affichez tous les processus du système en filtrant ceux dans l'état 'Z' (zombie)
ps -elf | grep ' Z '
# Ou utilisez l'option 'aux' (la 8ème colonne ($8) est l'état (STAT))
ps aux | awk '$8=="Z"'
Exemple de sortie :
# ps -elf | grep ' Z '
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 Z user 5021 5000 0 80 0 - 0 exit 15:30 ? 00:00:00 [defunct]
Les informations importantes dans l'exemple ci-dessus sont les suivantes :
-
S (État) :
Z(indiquant qu'il est en état de zombie) -
PID :
5021(c'est le PID du processus zombie) -
PPID :
5000(c'est le PID du processus parent qui n'a pas encore récolté le zombie) -
CMD :
[defunct](indiquant qu'il est terminé mais non nettoyé)
Comment résoudre un processus zombie
Le fait le plus important est que vous ne pouvez pas tuer un processus zombie avec la commande kill.
kill -9 5021(PID zombie de l'exemple ci-dessus)
Cette commande ne fonctionnera pas car le zombie est déjà dans un état "mort". Il n'y a pas d'entité pour gérer le signal kill.
La seule façon de résoudre un processus zombie est de faire en sorte que le processus parent appelle wait().
Étape 1 : Envoyer un signal au processus parent (recommandé)
La première chose à faire est d'envoyer manuellement le signal SIGCHLD au processus parent (PPID) pour lui demander de vérifier l'état de l'enfant.
# Envoi du signal SIGCHLD au parent PID (5000) de l'exemple
kill -s SIGCHLD 5000
Cela informe le processus parent que "l'un de vos processus enfants s'est terminé, veuillez vérifier !" Si le parent est programmé correctement, il recevra ce signal et ramassera le zombie pour le nettoyer.
Étape 2 : Terminer le processus parent de force (dernier recours)
Si la première étape ne fonctionne pas, cela signifie que le processus parent (PPID 5000) lui-même est bloqué, ou qu'il a un bogue sérieux dans la logique appelant wait().
Dans ce cas, terminer le processus parent de force est la seule solution.
# Terminer le processus parent (PPID 5000)
kill 5000
# Si cela ne fonctionne toujours pas, forcer la terminaison
kill -9 5000
Pourquoi cela résout-il le problème ?
Lorsque le processus parent est tué, ses processus enfants (processus orphelins) sont automatiquement adoptés par le init (PID 1) ou systemd. Le process init est conçu pour vérifier périodiquement l'état de ses enfants et récolter immédiatement ceux qui sont terminés (y compris les zombies).
Donc, si le parent problématique (PPID 5000) est tué, le zombie (PID 5021) devient le nouvel enfant de init, et init le nettoiera immédiatement.
⚠️ Attention : Avant de tuer le processus parent, assurez-vous en exécutant
ps -p 5000(PID parent) que ce processus n'est pas un service critique pour le système (par exemple, base de données, serveur web, etc.). Tuer un service critique de force pourrait entraîner des problèmes plus graves.
Résumé
-
Un processus zombie est un résidu dans la table des processus d'un processus qui s'est terminé mais dont l'état de terminaison n'a pas été récolté par le parent.
-
Il ne consomme pas de ressources, mais occupe un PID, et s'il y en a trop, cela peut provoquer des pannes système.
-
Vous pouvez trouver des zombies (PID) et leurs parents (PPID) avec la commande
ps -elf | grep ' Z '. -
Les solutions ciblent le processus parent (PPID) plutôt que le zombie.
-
kill -s SIGCHLD <parentPID>(recommandé) -
kill <parentPID>(dernier recours)
-
Aucun commentaire.