L'envoi de kill -9 à un processus n'exige pas la coopération du processus (comme la gestion d'un signal), il le tue simplement.
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 plain kill
n'est pas toujours efficace - cela signifie généralement que quelque chose a mal tourné dans le gestionnaire de processus. 1
Si 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
(voir man 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.
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 passe simplement par cette table et libère les ressources une par une?
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).
Les pages de manuel parlent de "signaux" mais ce n’est sûrement qu’une abstraction.
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:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void sighandler (int signum, siginfo_t *info, void *context) {
fprintf (
stderr,
"Received %d from pid %u, uid %u.\n",
info->si_signo,
info->si_pid,
info->si_uid
);
}
int main (void) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
while (1) sleep(10);
return 0;
}
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:
Received 15 from pid 25331, uid 1066.
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'utilisez kill -9
, il n'a pas cette chance, alors ne le faites que si la partie "exit volontairement" semble avoir échoué.
kill -9
Référence obligatoire .