Dans un commentaire sur cette réponse à une autre question , le commentateur dit:
n'utilisez pas kill -9 sauf si c'est absolument nécessaire! SIGKILL ne peut pas être piégé, donc le programme tué ne peut exécuter aucune routine d'arrêt pour par exemple effacer les fichiers temporaires. Essayez d'abord HUP (1), puis INT (2), puis QUIT (3)
Je suis d'accord sur le principe SIGKILL
, mais le reste est une nouvelle pour moi. Étant donné que le signal par défaut envoyé par kill
est SIGTERM
, je m'attendrais à ce que ce soit le signal le plus couramment attendu pour l'arrêt progressif d'un processus arbitraire. En outre, j'ai vu SIGHUP
utilisé pour des raisons non terminales, telles que dire à un démon "relisez votre fichier de configuration". Et il me semble que SIGINT
(la même interruption que vous obtenez généralement avec Ctrl-C, n'est-ce pas?) N'est pas aussi largement supportée qu'elle devrait l'être, ou se termine plutôt sans grâce.
Étant donné qu'il SIGKILL
s'agit d'un dernier recours - Quels signaux, et dans quel ordre , devez-vous envoyer à un processus arbitraire, afin de l'arrêter le plus gracieusement possible?
Veuillez étayer vos réponses avec des faits à l'appui (au-delà de vos préférences ou opinions personnelles) ou des références, si vous le pouvez.
Remarque: je suis particulièrement intéressé par les meilleures pratiques qui incluent la prise en compte de bash / Cygwin.
Edit: Jusqu'à présent, personne ne semble mentionner INT ou QUIT, et il y a une mention limitée de HUP. Y a-t-il une raison de les inclure dans un processus de mise à mort ordonné?
la source
Réponses:
SIGTERM demande à une application de se terminer. Les autres signaux indiquent à l'application d'autres choses qui ne sont pas liées à l'arrêt mais qui peuvent parfois avoir le même résultat. Ne les utilisez pas. Si vous souhaitez qu'une application s'arrête, dites-lui de le faire. Ne lui donnez pas de signaux trompeurs.
Certaines personnes pensent que la manière standard intelligente de terminer un processus consiste à lui envoyer une multitude de signaux, tels que HUP, INT, TERM et enfin KILL. C'est ridicule. Le bon signal pour la terminaison est SIGTERM et si SIGTERM ne termine pas le processus instantanément, comme vous pourriez le préférer, c'est parce que l'application a choisi de gérer le signal. Ce qui signifie qu'il a une très bonne raison de ne pas s'arrêter immédiatement: il y a un travail de nettoyage à faire. Si vous interrompez ce travail de nettoyage avec d'autres signaux, il est impossible de dire quelles données de la mémoire elles n'ont pas encore sauvegardées sur le disque, quelles applications clientes sont laissées en suspens ou si vous l'interrompez "au milieu de la phrase", ce qui est en fait une corruption de données.
Pour plus d'informations sur la signification réelle des signaux, voir sigaction (2). Ne confondez pas "Action par défaut" avec "Description", ce n'est pas la même chose.
SIGINT est utilisé pour signaler une "interruption clavier" interactive du processus. Certains programmes peuvent gérer la situation d'une manière spéciale pour les utilisateurs de terminaux.
SIGHUP est utilisé pour signaler que le terminal a disparu et ne regarde plus le processus. C'est tout. Certains processus choisissent de s'arrêter en réponse, généralement parce que leur fonctionnement n'a aucun sens sans un terminal, certains choisissent de faire d'autres choses telles que revérifier les fichiers de configuration.
SIGKILL est utilisé pour supprimer de force le processus du noyau. Il est spécial en ce sens qu'il ne s'agit pas en fait d'un signal adressé au processus mais qu'il est plutôt directement interprété par le noyau.
N'envoyez pas SIGKILL. SIGKILL ne devrait certainement jamais être envoyé par des scripts. Si l'application gère le SIGTERM, le nettoyage peut prendre une seconde, cela peut prendre une minute, cela peut prendre une heure . En fonction de ce que l'application doit faire avant qu'elle ne soit prête à se terminer. Toute logique qui " suppose " la séquence de nettoyage d'une application a pris suffisamment de temps et doit être raccourcie ou SIGKILLed après X secondes est tout simplement fausse .
La seule raison pour laquelle une application aurait besoin d' un SIGKILL pour se terminer, est si quelque chose a été bugué pendant sa séquence de nettoyage. Dans ce cas, vous pouvez ouvrir un terminal et le SIGKILL manuellement. En dehors de cela, la seule autre raison pour laquelle vous SIGKILLZ quelque chose est parce que vous VOULEZ l' empêcher de se nettoyer.
Même si la moitié du monde envoie aveuglément SIGKILL après 5 secondes, c'est toujours une chose horriblement mal à faire.
la source
Réponse courte : Envoyer
SIGTERM
, 30 secondes plus tard,SIGKILL
. Autrement dit, envoyezSIGTERM
, attendez un peu (cela peut varier d'un programme à l'autre, vous connaissez peut-être mieux votre système, mais 5 à 30 secondes suffisent. Lors de l'arrêt d'une machine, vous pouvez la voir attendre automatiquement jusqu'à 1'30s. Pourquoi la hâte, après tout?), Puis envoyezSIGKILL
.Raisonnable Réponse :
SIGTERM
,SIGINT
,SIGKILL
C'est plus que suffisant. Le processus se terminera très probablement avantSIGKILL
.Réponse longue :
SIGTERM
,SIGINT
,SIGQUIT
,SIGABRT
,SIGKILL
Cela n'est pas nécessaire, mais au moins vous n'induisez pas en erreur le processus concernant votre message. Tous ces signaux ne signifient que vous voulez que le processus pour arrêter ce qu'il fait et la sortie.
Quelle que soit la réponse que vous choisissez dans cette explication, gardez cela à l'esprit!
Si vous envoyez un signal qui signifie autre chose, le processus peut le gérer de manière très différente (d'une part). D'un autre côté, si le processus ne gère pas le signal, peu importe ce que vous envoyez après tout, le processus s'arrêtera de toute façon (lorsque l'action par défaut est de se terminer, bien sûr).
Donc, vous devez penser comme vous-même en tant que programmeur. Coderiez-vous un gestionnaire de fonctions pour, disons,
SIGHUP
quitter un programme qui se connecte à quelque chose, ou le feriez-vous en boucle pour essayer de vous connecter à nouveau? Telle est la question principale ici! C'est pourquoi il est important d'envoyer simplement des signaux qui signifient ce que vous souhaitez.Réponse longue presque stupide :
Le tableau ci-dessous contient les signaux pertinents et les actions par défaut au cas où le programme ne les gère pas.
Je les ai commandés dans l'ordre que je suggère d'utiliser (BTW, je vous suggère d'utiliser la réponse raisonnable , pas celle-ci ici), si vous avez vraiment besoin de tous les essayer (ce serait amusant de dire que la table est ordonnée en termes de la destruction qu'ils peuvent causer, mais ce n'est pas tout à fait vrai).
Les signaux avec un astérisque (*) ne sont PAS recommandés. La chose importante à ce sujet est que vous ne saurez peut-être jamais ce pour quoi il est programmé. Surtout
SIGUSR
! Cela peut démarrer l'apocalipse (c'est un signal gratuit pour un programmeur qui fait ce qu'il veut!). Mais, s'il n'est pas traité OU dans le cas peu probable où il est traité pour se terminer, le programme se terminera.Dans le tableau, les signaux avec les options par défaut pour terminer et générer un vidage de mémoire sont laissés à la fin, juste avant
SIGKILL
.Ensuite , je suggère pour cette longue réponse presque stupide :
SIGTERM
,SIGINT
,SIGHUP
,SIGPIPE
,SIGQUIT
,SIGABRT
,SIGKILL
Et enfin, le
Réponse longue et longue définitivement stupide :
N'essayez pas ca a la maison.
SIGTERM
,SIGINT
,SIGHUP
,SIGPIPE
,SIGALRM
,SIGUSR2
,SIGUSR1
,SIGQUIT
,SIGABRT
,SIGSEGV
,SIGILL
,SIGFPE
Et si rien ne fonctionnait,SIGKILL
.SIGUSR2
devrait être essayé avantSIGUSR1
car nous sommes mieux si le programme ne gère pas le signal. Et il est beaucoup plus probable qu'il gèreSIGUSR1
s'il ne gère qu'un seul d'entre eux.BTW, the KILL : il n'est pas faux d'envoyer
SIGKILL
à un processus, comme une autre réponse l'a indiqué. Eh bien, pensez à ce qui se passe lorsque vous envoyez uneshutdown
commande? Il essaieraSIGTERM
etSIGKILL
seulement. Pourquoi pensez-vous que c'est le cas? Et pourquoi avez-vous besoin d'autres signaux, si lashutdown
commande même n'utilise que ces deux?Maintenant, revenons à la longue réponse , c'est un joli oneliner:
for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done
Il dort pendant 30 secondes entre les signaux. Sinon, pourquoi auriez-vous besoin d'un oneliner ? ;)
Aussi, recommandé: essayez-le avec uniquement les signaux
15 2 9
de la réponse raisonnable .sécurité : retirez le second
echo
lorsque vous êtes prêt à partir. Je l'appelle mondry-run
pour les onliners . Utilisez-le toujours pour tester.Script tuer avec grâce
En fait, j'étais tellement intrigué par cette question que j'ai décidé de créer un petit script pour faire exactement cela. N'hésitez pas à le télécharger (cloner) ici:
Lien GitHub vers le référentiel Killgracefully
la source
En règle générale, vous enverriez
SIGTERM
, la valeur par défaut de kill. C'est la valeur par défaut pour une raison. Ce n'est que si un programme ne s'arrête pas dans un délai raisonnable que vous devez recourir àSIGKILL
. Mais notez qu'avecSIGKILL
le programme n'a aucune possibilité de nettoyer les choses et les données pourraient être corrompues.Quant à
SIGHUP
,HUP
signifie "raccrocher" et signifie historiquement que le modem s'est déconnecté. C'est essentiellement équivalent àSIGTERM
. La raison pour laquelle les démons utilisent parfoisSIGHUP
pour redémarrer ou recharger la configuration est que les démons se détachent de tout terminal de contrôle car un démon n'en a pas besoin et ne les reçoit donc jamaisSIGHUP
, de sorte que le signal a été considéré comme "libéré" pour une utilisation générale. Tous les démons ne l'utilisent pas pour recharger! L'action par défaut pour SIGHUP est de se terminer et de nombreux démons se comportent de cette façon! Vous ne pouvez donc pas envoyer aveuglément desSIGHUP
s aux démons et vous attendre à ce qu'ils survivent.Edit:
SIGINT
est probablement inapproprié pour terminer un processus, car il est normalement lié^C
ou quel que soit le paramètre du terminal pour interrompre un programme. De nombreux programmes capturent cela à leurs propres fins, il est donc assez courant pour que cela ne fonctionne pas.SIGQUIT
a généralement la valeur par défaut de créer un vidage de mémoire, et à moins que vous ne vouliez que les fichiers de base soient installés, ce n'est pas non plus un bon candidat.Résumé: si vous envoyez
SIGTERM
et que le programme ne meurt pas dans votre délai, envoyez-leSIGKILL
.la source
SIGTERM
signifie en fait envoyer à une application un message: « seriez-vous si gentil et vous suicideriez-vous ». Il peut être piégé et géré par l'application pour exécuter le code de nettoyage et d'arrêt.SIGKILL
ne peut pas être piégé par l'application. L'application est tuée par le système d'exploitation sans aucune chance de nettoyage.Il est courant d'envoyer d'
SIGTERM
abord, de dormir quelque temps, puis d'envoyerSIGKILL
.la source
la source
Avec toute la discussion en cours ici, aucun code n'a été proposé. Voici ma prise:
#!/bin/bash $pid = 1234 echo "Killing process $pid..." kill $pid waitAttempts=30 for i in $(seq 1 $waitAttempts) do echo "Checking if process is alive (attempt #$i / $waitAttempts)..." sleep 1 if ps -p $pid > /dev/null then echo "Process $pid is still running" else echo "Process $pid has shut down successfully" break fi done if ps -p $pid > /dev/null then echo "Could not shut down process $pid gracefully - killing it forcibly..." kill -SIGKILL $pid fi
la source
HUP me semble être des ordures. Je l'enverrais pour qu'un démon relise sa configuration.
SIGTERM peut être intercepté; vos démons peuvent simplement avoir un code de nettoyage à exécuter lorsqu'ils reçoivent ce signal. Vous ne pouvez pas faire cela pour SIGKILL. Ainsi, avec SIGKILL, vous ne donnez aucune option à l'auteur du démon.
Plus à ce sujet sur Wikipedia
la source