Question

Dans un commentaire sur cette réponse d'un autre question , l'intervenant dit:

  

ne pas utiliser kill -9, sauf si absolument   nécessaire! SIGKILL ne peut pas être pris au piège si   le programme tué ne peut pas exécuter une   routines d'arrêt de par exemple effacer   fichiers temporaires. Essayez d'abord HUP (1),   puis INT (2), puis QUIT (3)

Je suis d'accord en principe sur les SIGKILL, mais le reste est nouvelles pour moi. Étant donné que le signal envoyé par défaut par kill est SIGTERM, je pense qu'il est le signal le plus communément prévu pour un arrêt progressif d'un processus arbitraire. De plus, je l'ai vu SIGHUP utilisé pour des raisons non-terminaison, comme dit un démon « relire votre fichier de configuration. » Et il me semble que SIGINT (même vous interrompez auriez obtenez généralement avec Ctrl-C, non?) Ne sont pas aussi largement pris en charge comme il devrait être, ou plutôt disgracieuse se termine.

Étant donné que SIGKILL est un dernier recours - Quels sont les signaux, et dans quel ordre , si vous envoyer à un processus arbitraire, afin de le fermer aussi gracieusement que possible

S'il vous plaît justifier vos réponses avec des faits d'appui (au-delà de la préférence personnelle ou d'opinion) ou des références, si vous le pouvez.

Note:. Je suis particulièrement intéressé par les meilleures pratiques qui tiennent compte de bash / Cygwin

Modifier Jusqu'à présent, personne ne semble parler INT ou QUIT, et il y a mention limitée de HUP. Y at-il raison d'inclure dans un processus ordonné-mort?

Était-ce utile?

La solution

SIGTERM indique une demande de mettre fin. Les autres signaux indiquent l'application d'autres choses qui ne sont pas liés à l'arrêt, mais peuvent parfois avoir le même résultat. Ne pas utiliser ceux-ci. Si vous voulez une application pour arrêter, dire à. Ne pas donner des signaux trompeurs.

Certaines personnes croient que la manière standard intelligente de mettre fin à un processus est en lui envoyant un grand nombre de signaux, tels que HUP, INT, TERM et enfin TUER. C'est ridicule. Le signal droit de résiliation est SIGTERM et si SIGTERM ne se termine pas le processus instantanément, comme vous préférez peut-être, c'est parce que l'application a choisi de traiter le signal. Ce qui signifie qu'il a une très bonne raison de ne pas résilier immédiatement: Il a obtenu le travail de nettoyage à faire. Si vous interrompez que le travail de nettoyage avec d'autres signaux, on ne sait pas quelles sont les données de la mémoire, il n'a pas encore enregistré sur le disque, ce que les applications client sont laissées en suspens ou si vous l'interrompre « la mi-phrase » qui est effectivement la corruption de données.

Pour plus d'informations sur ce que le sens réel des signaux est, voir sigaction (2). Ne pas confondre « action par défaut » avec « Description », ils ne sont pas la même chose.

SIGINT est utilisé pour signaler une « interruption de clavier » interactive du processus. Certains programmes peuvent gérer la situation d'une manière spéciale dans le but des utilisateurs de terminaux.

SIGHUP est utilisé pour signaler que le terminal a disparu et ne cherche plus le processus. C'est tout. Certains processus choisissent de fermer en réponse, généralement parce que leur fonctionnement n'a pas de sens sans un terminal, certains choisissent de faire d'autres choses telles que les fichiers de configuration de nouveau contrôle.

SIGKILL est utilisé pour enlever avec force le processus du noyau. Il est spécial dans le sens où ce n'est pas en fait un signal au processus, mais plutôt est interprété par le noyau directement.

Ne pas envoyer SIGKILL. SIGKILL devrait certainement jamais être envoyé par les scripts. Si l'application gère le SIGTERM, il peut prendre une seconde pour le nettoyage, il peut prendre une minute, il peut prendre une heure . En fonction de ce que l'application doit se faire avant qu'il ne soit prêt à la fin. Toute logique « prend » La séquence de nettoyage d'une application a pris assez longtemps et doit être raccourci ou SIGKILLed après X secondes est tout simplement faux .

La seule raison pour laquelle une demande serait besoin SIGKILL mettre fin, est si quelque chose mis sur écoute pendant sa séquence de nettoyage. Dans ce cas, vous pouvez ouvrir un terminal et sigkill manuellement. Mis à part cela, la seule autre raison pour laquelle vous auriez sigkill quelque chose parce que vous VOULEZ pour l'empêcher de se nettoyer.

Même si la moitié du monde envoie aveuglément SIGKILL après 5 secondes, il est toujours chose horriblement mal à faire.

Autres conseils

Réponse courte : Envoyer SIGTERM, 30 secondes plus tard, SIGKILL. Autrement dit, envoyer SIGTERM, attendez un peu (peut varier d'un programme à, vous savez peut-être votre meilleur système, mais 5 à 30 secondes suffisent. Lors de l'arrêt d'une machine, vous pouvez le voir attendre automatiquement jusqu'à 1'30s . Pourquoi la hâte, après tout?), puis envoyez-SIGKILL.

Réponse raisonnable : SIGTERM, SIGINT, SIGKILL Ceci est plus que suffisant. Le processus très probablement avant fin SIGKILL.

Réponse longue : SIGTERM, SIGINT, SIGQUIT, SIGABRT, SIGKILL

Ceci est inutile, mais au moins vous n'êtes pas induire en erreur le processus en ce qui concerne votre message. Tous ces signaux faire signifie que vous voulez que le processus pour arrêter ce qu'il fait et la sortie.

Peu importe quelle réponse vous choisissez de cette explication, gardez cela à l'esprit!

Si vous envoyez un signal qui signifie quelque chose d'autre, le processus peut gérer de manière très différente (d'une part). D'autre part, si le processus ne gère pas le signal, peu importe ce que vous envoyez après tout, le processus quittera de toute façon (lorsque l'action par défaut est de mettre fin, bien sûr).

Alors, vous devez penser que vous en tant que programmeur. Voulez-vous coder un gestionnaire de fonction pour, disons, SIGHUP de quitter un programme qui se connecte avec quelque chose, ou si vous en boucle pour essayer de se connecter à nouveau? Telle est la principale question ici! Voilà pourquoi il est important d'envoyer simplement des signaux qui signifient ce que vous avez l'intention.

Presque stupide Réponse longue :

Le tableau ci dessous contient les signaux pertinents, et les actions par défaut dans le cas où le programme ne les gère pas.

Je les ai commandé dans l'ordre que je suggère d'utiliser (BTW, je vous suggère d'utiliser le réponse raisonnable , pas celui-là), si vous avez vraiment besoin de les essayer (ce serait amusant de dire la table est ordonnée en termes de destruction qu'ils peuvent causer, mais ce n'est pas complètement true).

Les signaux d'un astérisque (*) sont pas recommandé. La chose importante à propos de ces derniers est que vous ne pouvez jamais savoir ce qu'il est programmé pour faire. Spécialement SIGUSR! Il peut démarrer le apocalipse (il est un signal gratuit pour un programmeur faire ce qu'il / elle veut!). Mais, en cas de manipulation ou dans le cas peu probable, il est traité de mettre fin, le programme prendra fin.

Dans le tableau, les signaux avec les options par défaut pour terminer et générer une décharge de base sont laissés à la fin, juste avant SIGKILL.

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGTERM      15       Term    Termination signal
SIGINT        2       Term    Famous CONTROL+C interrupt from keyboard
SIGHUP        1       Term    Disconnected terminal or parent died
SIGPIPE      13       Term    Broken pipe
SIGALRM(*)   14       Term    Timer signal from alarm
SIGUSR2(*)   12       Term    User-defined signal 2
SIGUSR1(*)   10       Term    User-defined signal 1
SIGQUIT       3       Core    CONTRL+\ or quit from keyboard
SIGABRT       6       Core    Abort signal from abort(3)
SIGSEGV      11       Core    Invalid memory reference
SIGILL        4       Core    Illegal Instruction
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal

Alors je suggère pour cette longue réponse presque stupide : SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGQUIT, SIGABRT, SIGKILL

Et enfin, le

Définitivement réponse stupide Long Long :

Ne pas essayer à la maison.

SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGALRM, SIGUSR2, SIGUSR1, SIGQUIT, SIGABRT, SIGSEGV, SIGILL, SIGFPE et si rien ne fonctionnait, SIGKILL.

SIGUSR2 doit être jugé avant SIGUSR1 parce que nous sommes mieux lotis si le programme ne gère pas le signal. Et il est beaucoup plus probable à gérer SIGUSR1 si elle gère seul d'entre eux.

BTW, la KILL : il n'a pas tort d'envoyer SIGKILL à un processus, comme autre réponse dit. Eh bien, pensez ce qui se passe lorsque vous envoyez une commande shutdown? Il va essayer SIGTERM et SIGKILL seulement. Pourquoi pensez-vous que c'est le cas? Et pourquoi avez-vous desd'autres signaux, si la commande très shutdown utilise uniquement ces deux?


Maintenant, retour à la longue réponse , c'est une belle 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 ? ;)

En outre, recommandé: essayer avec uniquement 15 2 9 de la réponse raisonnable .

sécurité : enlever la deuxième echo lorsque vous êtes prêt à aller. Je l'appelle mon dry-run pour onliners . Toujours utiliser pour tester.


Script killgracefully

En fait, j'étais tellement intrigué par cette question que j'ai décidé de créer un petit script pour le faire. S'il vous plaît, ne hésitez pas à télécharger (clone) ici:

Killgracefully dépôt

En général, vous enverriez SIGTERM, la valeur par défaut de tuer. Il est la valeur par défaut pour une raison. Seulement si un programme ne se arrête pas dans un laps de temps raisonnable si vous recours à SIGKILL. Mais notez que le programme SIGKILL n'a pas la possibilité de nettoyer les choses données und pourraient être corrompues.

En ce qui concerne SIGHUP, HUP signifie « raccrocher » et signifiait historiquement que le modem déconnecté. Il est essentiellement équivalent à SIGTERM. La raison pour laquelle daemons utilisent parfois SIGHUP pour redémarrer ou recharger config est que daemons détacher de tout terminal de contrôle en tant que démon n'a pas besoin de ceux-ci et ne serait donc jamais recevoir SIGHUP, de sorte que le signal a été considéré comme « libéré » pour un usage général. Tous les daemons utilisent cela pour reload! L'action par défaut pour SIGHUP est de mettre fin et de nombreux démons se comportent de cette façon! Donc, vous ne pouvez pas envoyer aveuglément SIGHUPs à daemons et les attendant à survivre.

Modifier SIGINT est probablement inapproprié de mettre fin à un processus, car il est normalement lié à ^C ou quel que soit le réglage terminal est d'interrompre un programme. De nombreux programmes capturent ce pour leurs propres fins, il est donc assez commune pour ne pas travailler. SIGQUIT a généralement la valeur par défaut de la création d'une décharge de base, et à moins que vous voulez que les fichiers de base autour de la pose, il est pas un bon candidat, que ce soit.

Résumé:. Si vous envoyez SIGTERM et le programme ne meurt pas dans votre calendrier puis envoyez-le SIGKILL

SIGTERM signifie réellement l'envoi d'une application, un message: " seriez-vous si gentil et de se suicider ". Il peut être pris au piège et pris en charge par l'application pour exécuter le code de nettoyage et d'arrêt.

SIGKILL ne peut pas être pris au piège par l'application. L'application se fait tuer par OS sans aucune chance pour le nettoyage.

Il est typique d'envoyer d'abord SIGTERM, dormir un peu de temps, puis envoyer SIGKILL.

  • SIGTERM est équivalent à "cliquer sur le 'X'" dans une fenêtre.
  • SIGTERM est ce que Linux utilise d'abord, quand il est en cours d'arrêt.

Avec toutes les discussions qui se passe ici, aucun code n'a été offert. Voici mon:

#!/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

HUP ressemble à ordures pour moi. Je l'envoie pour obtenir un démon à relire sa configuration.

SIGTERM peuvent être interceptées; vos daemons pourraient bien avoir le code de nettoyage pour fonctionner lorsqu'il reçoit ce signal. Vous ne pouvez pas le faire pour SIGKILL. Ainsi, avec SIGKILL vous ne donnez aucune option l'auteur du démon.

En savoir plus sur ce sur Wikipedia

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top