Cela me laisse souvent perplexe de constater que, même si je travaille professionnellement avec les ordinateurs depuis plusieurs décennies et Linux depuis une décennie, je traite en réalité la plupart des fonctionnalités du système d'exploitation comme une boîte noire, un peu comme la magie.
Aujourd'hui, j'ai pensé à la kill
commande, et même si je l'utilise plusieurs fois par jour (tant par sa "normale" que par sa -9
saveur), je dois avouer que je ne sais absolument pas comment elle fonctionne en arrière-plan.
De mon point de vue, si un processus en cours est "bloqué", j'appelle kill
son PID, puis il ne fonctionne plus du tout. La magie!
Qu'est-ce qui se passe vraiment là-bas? Les pages de manuel parlent de "signaux", mais ce n’est sûrement qu’une abstraction. L'envoi kill -9
à un processus ne nécessite pas la coopération du processus (comme la gestion d'un signal), il le tue simplement.
- Comment Linux empêche-t-il le processus de continuer à utiliser son temps processeur?
- Est-il retiré de la planification?
- Déconnecte-t-il le processus de ses handles de fichiers ouverts?
- Comment la mémoire virtuelle du processus est-elle libérée?
- Y a-t-il quelque chose comme une table globale en mémoire, où Linux garde des références à toutes les ressources occupées par un processus, et quand je "tue" un processus, Linux parcourt simplement cette table et libère les ressources une par une?
J'aimerais vraiment savoir tout ça!
la source
kill -9
Référence obligatoire .Réponses:
Vous présumez que parce que certains signaux peuvent être captés et ignorés, ils impliquent tous une coopération. Mais, comme indiqué
man 2 signal
, "les signaux SIGKILL et SIGSTOP ne peuvent être ni capturés ni ignorés". SIGTERM peut être intercepté, raison pour laquelle plainkill
n'est pas toujours efficace - cela signifie généralement que quelque chose a mal tourné dans le gestionnaire de processus. 1Si un processus ne définit pas (ou ne peut pas) définir un gestionnaire pour un signal donné, le noyau effectue une action par défaut. Dans le cas de SIGTERM et SIGKILL, il s’agit de mettre fin au processus (sauf si son PID est 1; le noyau ne se terminera pas
init
) 2, ce qui signifie que ses descripteurs de fichier sont fermés, sa mémoire est renvoyée dans le pool système, son parent reçoit SIGCHILD, son orphelin. les enfants sont hérités par init, etc., comme si elle avait appeléexit
(voirman 2 exit
). Le processus n'existe plus - à moins qu'il ne devienne un zombie, auquel cas il est toujours répertorié dans la table des processus du noyau avec certaines informations; cela se produit lorsque son parent newait
et traiter correctement ces informations. Cependant, les processus zombies ne disposent plus de mémoire et ne peuvent donc pas continuer à s'exécuter.Je pense que c'est assez précis. La mémoire physique est suivie par page (une page correspond généralement à un bloc de 4 Ko) et ces pages sont extraites et renvoyées dans un pool global. C'est un peu plus compliqué en ce sens que certaines pages libérées sont mises en cache au cas où les données qu'elles contiennent seraient à nouveau requises (c'est-à-dire des données qui ont été lues à partir d'un fichier existant).
Bien sûr, tous les signaux sont une abstraction. Ils sont conceptuels, tout comme les "processus". Je joue un peu la sémantique, mais si vous voulez dire que SIGKILL est qualitativement différent de SIGTERM, alors oui et non. Oui dans le sens où cela ne peut pas être attrapé, mais non dans le sens où ce sont deux signaux. Par analogie, une pomme n'est pas une orange, mais les pommes et les oranges sont, selon une définition préconçue, les deux fruits. SIGKILL semble plus abstrait puisque vous ne pouvez pas l'attraper, mais c'est toujours un signal. Voici un exemple de traitement par SIGTERM. Je suis sûr que vous avez déjà vu ces exemples:
Ce processus ne fera que dormir pour toujours. Vous pouvez l'exécuter dans un terminal et l'envoyer avec SIGTERM
kill
. Il crache des choses comme:1066 est mon UID. Le PID sera celui du shell à partir duquel
kill
est exécuté, ou le PID de kill si vous le branchez (kill 25309 & echo $?
).Là encore, il est inutile de définir un gestionnaire pour SIGKILL car cela ne fonctionnera pas. 3 Si
kill -9 25309
le processus se termine. Mais c'est toujours un signal. le noyau a l'information sur qui a envoyé le signal , de quel type de signal il s'agit, etc.1. Si vous n'avez pas consulté la liste des signaux possibles , voir
kill -l
.2. Une autre exception, comme Tim Post le mentionne ci-dessous, s’applique aux processus en sommeil ininterruptible . Ceux-ci ne peuvent pas être réveillés tant que le problème sous-jacent n'est pas résolu. Par conséquent, TOUS les signaux (y compris SIGKILL) sont différés pour la durée. Un processus ne peut toutefois pas créer cette situation exprès.
3. Cela ne signifie pas que l’utilisation
kill -9
est une meilleure chose à faire en pratique. Mon exemple de gestionnaire est mauvais en ce sens qu'il ne mène pas àexit()
. Le véritable objectif d’un gestionnaire SIGTERM est de donner au processus la possibilité de nettoyer, par exemple, des fichiers temporaires, puis de le quitter volontairement. Si vous l'utilisezkill -9
, il n'a pas cette chance, alors ne le faites que si la partie "exit volontairement" semble avoir échoué.la source
-9
parce que c’est le vrai problème, qui veut que celui-ci meure! ;)kill -9
certains processus liés aux E / S ne va pas marcher, du moins pas tout de suite.kill -9
, dans la mesure où un processus qui ne peut être capturé, un processus le recevant ne peut effectuer aucun nettoyage (par exemple, supprimer des fichiers temporaires, libérer de la mémoire partagée, etc.) avant de se fermer. Par conséquent, utilisezkill -9
(akakill -kill
) seulement en dernier recours. Commencez par akill -hup
et / ou d'kill -term
abord, puis utilisez-lekill -kill
comme coup de grâce.Chaque processus s'exécute à l'heure programmée puis est interrompu par une minuterie matérielle pour donner le cœur de son processeur à d'autres tâches. C'est pourquoi il est possible d'avoir beaucoup plus de processus qu'il n'y a de cœurs de processeur, ou même d'exécuter tous les systèmes d'exploitation avec beaucoup de processus sur un seul processeur.
Une fois le processus interrompu, le contrôle revient au code du noyau. Ce code peut alors prendre la décision de ne pas reprendre l'exécution du processus interrompu, sans aucune coopération de la part du processus. kill -9 peut finir par être exécuté dans n’importe quelle ligne de votre programme.
la source
Voici une description idéalisée du fonctionnement d'un processus. En pratique, toute variante Unix comportera de nombreuses complications et optimisations supplémentaires.
Le noyau a une structure de données pour chaque processus qui stocke des informations sur la mémoire qu'il mappe, ses threads et son calendrier, les fichiers ouverts, etc. Si le noyau décide de supprimer un processus, il note la structure de données du processus (et peut-être dans la structure de données de chacun des threads) que le processus doit être tué.
Si l'un des threads du processus est actuellement planifié sur un autre processeur, le noyau peut déclencher une interruption sur cet autre CPU pour que ce thread cesse de s'exécuter plus rapidement.
Lorsque le planificateur constate qu'un thread est dans un processus qui doit être tué, il ne le planifie plus.
Lorsque plus aucun thread du processus n'est planifié, le noyau commence à libérer les ressources du processus (mémoire, descripteurs de fichier,…). Chaque fois que le noyau libère une ressource, il vérifie si son propriétaire dispose toujours de ressources actives. Une fois que le processus n'a plus aucune ressource active (mappage de la mémoire, descripteur de fichier ouvert,…), la structure de données du processus lui-même peut être libérée et l'entrée correspondante peut être supprimée de la table des processus.
Certaines ressources peuvent être libérées immédiatement (par exemple, désallocation de mémoire qui n'est pas utilisée par une opération d'E / S). D'autres ressources doivent attendre, par exemple, les données décrivant une opération d'E / S ne peuvent pas être libérées tant que l'opération est en cours (pendant qu'un DMA est en cours, la mémoire à laquelle il accède est utilisée et l'annulation de ce dernier nécessite contacter le périphérique). Le conducteur d'une telle ressource est notifié et peut tenter de hâter l'annulation; une fois que l'opération n'est plus en cours, le pilote termine la libération de cette ressource.
(L'entrée dans la table de processus est en fait une ressource appartenant au processus parent. Elle est libérée à la fin du processus et lorsque le parent reconnaît l'événement .)
la source