Sur les systèmes POSIX, les signaux de terminaison ont généralement l'ordre suivant (selon de nombreuses pages MAN et les spécifications POSIX):
SIGTERM - demandez poliment à un processus de se terminer. Il se terminera en douceur, nettoyant toutes les ressources (fichiers, sockets, processus enfants, etc.), supprimant les fichiers temporaires, etc.
SIGQUIT - demande plus énergique. Il se terminera de manière disgracieuse, nettoyant toujours les ressources qui ont absolument besoin d'être nettoyées, mais peut-être pas supprimer les fichiers temporaires, peut-être écrire des informations de débogage quelque part; sur certains systèmes, un vidage de mémoire sera également écrit (que le signal soit capté par l'application ou non).
SIGKILL - la demande la plus forte. On ne demande même pas au processus de faire quoi que ce soit, mais le système nettoiera le processus, que cela veuille ou non. Très probablement, un vidage de mémoire est écrit.
Comment SIGINT s'inscrit-il dans cette image? Un processus CLI est généralement terminé par SIGINT lorsque l'utilisateur frappe CRTL + C, cependant un processus d'arrière-plan peut également être terminé par SIGINT à l'aide de l'utilitaire KILL. Ce que je ne vois pas dans les spécifications ou les fichiers d'en-tête, c'est si SIGINT est plus ou moins puissant que SIGTERM ou s'il y a une différence entre SIGINT et SIGTERM.
METTRE À JOUR:
La meilleure description des signaux de terminaison que j'ai trouvée jusqu'à présent se trouve dans la documentation GNU LibC . Cela explique très bien qu'il existe une différence voulue entre SIGTERM et SIGQUIT.
Cela dit à propos de SIGTERM:
C'est la manière normale de demander poliment à un programme de se terminer.
Et cela dit à propos de SIGQUIT:
[...] et produit un vidage de mémoire quand il termine le processus, tout comme un signal d'erreur de programme. Vous pouvez considérer cela comme une condition d'erreur de programme «détectée» par l'utilisateur. [...] Il est préférable d'omettre certains types de nettoyages lors de la gestion de SIGQUIT. Par exemple, si le programme crée des fichiers temporaires, il doit gérer les autres demandes d'arrêt en supprimant les fichiers temporaires. Mais il vaut mieux que SIGQUIT ne les supprime pas, afin que l'utilisateur puisse les examiner conjointement avec le vidage de mémoire.
Et SIGHUP est également assez bien expliqué. SIGHUP n'est pas vraiment un signal de terminaison, cela signifie simplement que la "connexion" à l'utilisateur a été perdue, donc l'application ne peut pas s'attendre à ce que l'utilisateur lise une autre sortie (par exemple, la sortie stdout / stderr) et il n'y a aucune entrée à attendre du utilisateur plus. Pour la plupart des applications, cela signifie qu'il vaut mieux arrêter. En théorie, une application peut également décider qu'elle passe en mode démon lorsqu'un SIGHUP est reçu et s'exécute maintenant en tant que processus d'arrière-plan, en écrivant la sortie dans un fichier journal configuré. Pour la plupart des démons déjà exécutés en arrière-plan, SIGHUP signifie généralement qu'ils doivent réexaminer leurs fichiers de configuration, donc vous les envoyez aux processus d'arrière-plan après avoir édité les fichiers de configuration.
Cependant, il n'y a aucune explication utile de SIGINT sur cette page, à part qu'il est envoyé par CRTL + C. Y a-t-il une raison pour laquelle on traiterait SIGINT d'une manière différente de SIGTERM? Dans l'affirmative, quelle en serait la raison et en quoi le traitement serait-il différent?
sudo fuser -l
sur votre invite de commande. Pour moi, cela soulève:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
kill -l
une liste de signaux.Réponses:
SIGTERM et SIGKILL sont destinés aux demandes générales de «terminer ce processus». SIGTERM (par défaut) et SIGKILL (toujours) entraîneront l'arrêt du processus. SIGTERM peut être intercepté par le processus (par exemple pour qu'il puisse faire son propre nettoyage s'il le souhaite), ou même complètement ignoré; mais SIGKILL ne peut pas être attrapé ou ignoré.
SIGINT et SIGQUIT sont spécifiquement destinés aux demandes du terminal: des caractères d'entrée particuliers peuvent être affectés pour générer ces signaux (en fonction des paramètres de contrôle du terminal). L'action par défaut pour SIGINT est le même type d'arrêt de processus que l'action par défaut pour SIGTERM et l'action immuable pour SIGKILL; L'action par défaut pour SIGQUIT est également l'arrêt du processus, mais des actions supplémentaires définies par l'implémentation peuvent se produire, telles que la génération d'un vidage mémoire. L'un ou l'autre peut être intercepté ou ignoré par le processus si nécessaire.
SIGHUP, comme vous le dites, est destiné à indiquer que la connexion du terminal a été perdue, plutôt qu'à être un signal de terminaison en tant que tel. Mais, encore une fois, l'action par défaut pour SIGHUP (si le processus ne l'attrape pas ou ne l'ignore pas) est de terminer le processus de la même manière que SIGTERM etc.
Il existe un tableau dans les définitions POSIX pour
signal.h
lequel répertorie les différents signaux et leurs actions et objectifs par défaut, et le chapitre Interface générale du terminal comprend beaucoup plus de détails sur les signaux liés au terminal.la source
Comme DarkDust l'a noté, de nombreux signaux ont les mêmes résultats, mais les processus peuvent leur attacher différentes actions en distinguant la manière dont chaque signal est généré. En regardant le code source du noyau FreeBSD (kern_sig.c), je vois que les deux signaux sont traités de la même manière, ils terminent le processus et sont livrés à n'importe quel thread.
la source
man 7 signal
Ceci est la page de manuel non normative pratique du projet de pages de manuel Linux que vous souhaitez souvent consulter pour obtenir des informations sur les signaux Linux.
La version 3.22 mentionne des choses intéressantes telles que:
et contient le tableau:
qui résume le signal
Action
qui distingue par exemple SIGQUIT de SIGQUIT, puisque SIGQUIT a une actionCore
et SIGINTTerm
.Les actions sont documentées dans le même document:
Je ne vois aucune différence entre SIGTERM et SIGINT du point de vue du noyau car les deux ont une action
Term
et les deux peuvent être capturés. Il semble que ce ne soit qu'une "distinction de convention d'usage courant":kill
Certains signaux sont ANSI C et d'autres non
Une différence considérable est que:
Ils sont décrits dans la section "7.14 Traitement des signaux" du projet C99 N1256 :
ce qui fait de SIGINT un bon candidat pour un Ctrl + C. interactif
POSIX 7
POSIX 7 documente les signaux avec l'en-
signal.h
tête: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.htmlCette page contient également le tableau d'intérêt suivant qui mentionne certaines des choses que nous avions déjà vues
man 7 signal
:Init BusyBox
La
reboot
commande par défaut 1.29.2 de BusyBox envoie un SIGTERM aux processus, se met en veille pendant une seconde, puis envoie SIGKILL. Cela semble être une convention commune dans différentes distributions.Lorsque vous arrêtez un système BusyBox avec:
il envoie un signal au processus d'initialisation.
Ensuite, le gestionnaire de signal init finit par appeler:
qui imprime sur le terminal:
En voici un exemple concret minimal .
Signaux envoyés par le noyau
la source
Après une recherche rapide sur Google pour sigint vs sigterm , il semble que la seule différence voulue entre les deux soit de savoir si elle a été initiée par un raccourci clavier ou par un appel explicite à
kill
.En conséquence, vous pourriez, par exemple, intercepter sigint et faire quelque chose de spécial avec, sachant qu'il a probablement été envoyé par un raccourci clavier. Peut-être rafraîchir l'écran ou quelque chose, au lieu de mourir (non recommandé, car les gens s'attendent
^C
à tuer le programme, juste un exemple).J'ai aussi appris que
^\
devrait envoyer sigquit, que je pourrais commencer à utiliser moi-même. Ça a l'air très utile.la source
En utilisant
kill
(à la fois l'appel système et l'utilitaire`, vous pouvez envoyer presque n'importe quel signal à n'importe quel processus, à condition que vous en ayez l'autorisation. Un processus ne peut pas distinguer comment un signal a pris vie et qui l'a envoyé.Cela étant dit, SIGINT est vraiment destiné à chanter l'interruption Ctrl-C, tandis que SIGTERM est le signal général du terminal. Il n'y a pas de concept d'un signal «plus puissant», à la seule exception qu'il y a des signaux qui ne peuvent pas être bloqués ou traités (SIGKILL et SIGSTOP, selon la page de manuel).
Un signal ne peut être "plus puissant" qu'un autre signal en ce qui concerne la façon dont un processus de réception gère le signal (et quelle est l'action par défaut pour ce signal). Par exemple, par défaut, SIGTERM et SIGINT mènent à la terminaison. Mais si vous ignorez SIGTERM, cela ne mettra pas fin à votre processus, contrairement à SIGINT.
la source
À l'exception de quelques signaux, les gestionnaires de signaux peuvent capter les différents signaux, ou le comportement par défaut à la réception d'un signal peut être modifié. Consultez la
signal(7)
page de manuel pour plus de détails.la source
SIGINT
signal (" interruption de programme ") est envoyé lorsque l'utilisateur tape le caractère INTR (normalementC-c
)." "SIGINT 2 Term Interrupt from keyboard" Vous appuyez sur Ctrl-C,SIGINT
est envoyé. Le processus meurt normalement. Que donner de plus?