Quand j'ai utilisé killall -9 name
pour tuer un programme, l'état devient zombie. Quelques minutes plus tard, ça s'est vraiment arrêté.
Alors, que se passe-t-il pendant ces minutes ?
Réponse acceptée :
Le programme ne reçoit en fait jamais le signal SIGKILL, car SIGKILL est entièrement géré par le système d'exploitation/noyau.
Lorsque SIGKILL pour un processus spécifique est envoyé, le planificateur du noyau arrête immédiatement de donner à ce processus plus de temps CPU pour exécuter le code de l'espace utilisateur. Si le processus a des threads exécutant du code de l'espace utilisateur sur d'autres processeurs/cœurs au moment où le planificateur prend cette décision, ces threads seront également arrêtés. (Dans les systèmes monocœur, cela était beaucoup plus simple :si le seul cœur du processeur du système exécutait le planificateur, il n'exécutait par définition pas le processus en même temps !)
Si le processus/thread exécute du code 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, cela devient un peu plus délicat :seuls certains appels système sont interruptibles, donc le le noyau marque en interne le processus comme étant dans un état spécial « en train de mourir » jusqu'à ce que les appels système ou les opérations d'E/S soient résolus. Le temps CPU pour les résoudre sera planifié 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 est en train de mourir à des points d'arrêt appropriés et se terminera plus tôt dans ce cas. Les opérations sans interruption s'exécuteront jusqu'à la fin et vérifieront un état "mort" juste avant de revenir au code de l'espace utilisateur.
Une fois que toutes les routines du noyau en cours de processus sont résolues, l'état du processus passe de "mourant" à "mort" et le noyau commence à le nettoyer, comme lorsqu'un programme se termine 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 désordonnés), et le processus passera à l'état "zombie" . Le parent du processus tué sera averti par un signal SIGCHLD.
Par conséquent, le processus lui-même n'aura jamais la possibilité 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 wait(2)
appel système. Fondamentalement, la seule ressource qu'un processus zombie consomme plus 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 sa mort.
Si le processus parent meurt avant ses enfants, les processus enfants orphelins sont automatiquement adoptés par le PID #1, qui a le devoir spécial de continuer à appeler wait(2)
afin que les processus orphelins ne restent pas des zombies.
S'il faut plusieurs minutes pour qu'un processus zombie s'efface, cela suggère que le parent processus du zombie est en difficulté ou ne fait pas son travail correctement.
Il y a une description ironique sur ce qu'il faut faire en cas de problèmes de zombies dans les systèmes d'exploitation de type Unix :« Vous ne pouvez rien faire pour les zombies eux-mêmes, car ils sont déjà morts. À la place, tuez le maléfique maître zombie ! " (c'est-à-dire le processus parent des zombies gênants)