Quand j'avais l'habitude killall -9 name
de tuer un programme, l'État devenait un zombie. Quelques minutes plus tard, ça s'est vraiment arrêté. Alors, que se passe-t-il pendant ces minutes?
En réalité, le programme ne reçoit jamais le signal SIGKILL, car SIGKILL est entièrement géré par le système d'exploitation / le noyau.
Lorsque SIGKILL est envoyé pour un processus spécifique, le planificateur du noyau arrête immédiatement de lui donner plus de temps CPU pour exécuter du code d'espace utilisateur. Si le processus a des threads exécutant le code d'espace utilisateur sur d'autres CPU / cœurs au moment où le planificateur prend cette décision, ces threads seront également arrêtés. (Dans les systèmes simple cœur, cela était beaucoup plus simple: si le seul cœur de processeur du système exécutait le planificateur, par définition, il n'exécutait pas le processus en même temps!)
Si le processus / thread exécute le code du noyau (par exemple, un appel système ou une opération d’E / S associée à un fichier mappé en mémoire) au moment de SIGKILL, la situation devient un peu plus délicate: seuls certains appels système sont interruptibles. Le noyau en interne marque le processus comme étant dans un état de "mort" spécial jusqu'à ce que les appels système ou les opérations d'E / S soient résolus. Le temps de calcul nécessaire pour les résoudre sera programmé comme d’habitude. Les appels système interruptibles ou les opérations d'E / S vérifieront si le processus qui les a appelés meurt à un point d'arrêt approprié, et se terminera plus tôt dans ce cas. Les opérations ininterruptibles s'achèveront et vérifieront l'état "en voie de disparition" juste avant de revenir au code d'espace utilisateur.
Une fois que toutes les routines du noyau en cours de traitement sont résolues, l'état du processus passe de "en train de mourir" à "en arrêt" et le noyau commence à le nettoyer, comme c'est le cas lorsqu'un programme se ferme normalement. Une fois le nettoyage terminé, un code de résultat supérieur à 128 sera attribué (pour indiquer que le processus a été tué par un signal; voir cette réponse pour les détails compliqués ) et le processus passera à l'état "zombie". . Le parent du processus tué sera informé par un signal SIGCHLD.
En conséquence, le processus lui-même n'aura jamais l'occasion de traiter réellement les informations qu'il a reçues d'un SIGKILL.
Lorsqu'un processus est dans un état "zombie", cela signifie que le processus est déjà mort, mais que son processus parent ne l'a pas encore reconnu en lisant le code de sortie du processus mort à l'aide de l' wait(2)
appel système. Fondamentalement, la seule ressource qu'un processus zombie consomme est un emplacement dans la table de processus qui contient son PID, le code de sortie et quelques autres "statistiques vitales" du processus au moment de son décès.
Si le processus parent meurt avant ses enfants, les processus enfants orphelins sont automatiquement adoptés par le PID n ° 1, qui a le devoir spécial de continuer à appeler wait(2)
pour que tout processus orphelin ne reste pas sous la forme de zombies.
Si le processus d'un zombie prend plusieurs minutes à se dégager, cela suggère que le processus parent du zombie se débat ou ne fait pas son travail correctement.
Dans les systèmes d'exploitation de type Unix, il existe une description ironique qui explique ce qu'il faut faire en cas de problèmes de zombies: "Vous ne pouvez rien faire pour les zombies eux-mêmes, car ils sont déjà morts. Au lieu de cela, tuez le méchant maître des zombies! " (ie le processus parent des zombies gênants)
ps
: 'S' est pour I / O attend que le noyau puisse annuler afin de fournir un signal, et 'D' pour ceux qu'il ne peut pas.