Domanda

In un commento SU questa risposta di un altro domanda, il commentatore dice:

non usare kill -9 a meno che non sia assolutamente necessario!SIGKILL non può essere intrappolato così Il programma Killed non può essere eseguito routine di spegnimento, ad es.cancellare file temporanei.Primo tentativo HUP (1), quindi INT (2), quindi QUIT (3)

Sono d'accordo in linea di principio su SIGKILL, ma il resto è una novità per me.Dato che il segnale predefinito inviato da kill È SIGTERM, mi aspetterei che sia il segnale più comunemente atteso per l'arresto ordinato di un processo arbitrario.Inoltre, ho visto SIGHUP usato per motivi non terminanti, come dire a un demone "rileggi il tuo file di configurazione". E mi sembra che SIGINT (la stessa interruzione che ottieni tipicamente con Ctrl-C, giusto?) non è ampiamente supportata come dovrebbe essere, o termina in modo piuttosto sgraziato.

Dato che SIGKILL è l'ultima risorsa - Quali segnali e in quale ordine, dovresti inviare un processo arbitrario, per chiuderlo nel modo più elegante possibile?

Per favore, se puoi, motiva le tue risposte con fatti a sostegno (oltre alle preferenze o opinioni personali) o riferimenti.

Nota:Sono particolarmente interessato alle migliori pratiche che includono la considerazione di bash/Cygwin.

Modificare: Finora nessuno sembra menzionare INT o QUIT e si parla solo limitatamente di HUP.C'è qualche motivo per includerli in un processo ordinato di uccisione?

È stato utile?

Soluzione

SIGTERM dice un'applicazione per terminare. Gli altri segnali indicano l'applicazione altre cose che sono estranei a l'arresto, ma a volte può avere lo stesso risultato. Non usare quelli. Se si desidera un'applicazione per arrestare, dillo. Non dare segnali fuorvianti.

Alcune persone ritengono che il modo intelligente di serie di terminare un processo è con l'invio di un gran numero di segnali, come HUP, INT, TERM e infine uccidere. Questo è ridicolo. Il segnale giusto per la terminazione è SIGTERM e se SIGTERM non termina il processo immediatamente, come si potrebbe preferire, è perché l'applicazione ha scelto di gestire il segnale. Il che significa che ha un ottimo motivo per non risolvere immediatamente: Essa ha avuto il lavoro di pulizia da fare. Se si interrompe che il lavoro di pulizia con altri segnali, non si può dire quali sono i dati dalla memoria non è ancora salvato su disco, quali applicazioni client sono lasciati appesi o se si sta interrompendo è "a metà della frase" che è efficacemente la corruzione dei dati.

Per ulteriori informazioni su ciò che il vero significato dei segnali è, vedere sigaction (2). Non confondere "Azione di default" con "Descrizione", non sono la stessa cosa.

SIGINT viene utilizzata per segnalare un interattivo "interrupt di tastiera" del processo. Alcuni programmi possono gestire la situazione in modo particolare allo scopo di utenti terminali.

SIGHUP viene utilizzato per segnalare che il terminale è scomparso e non è più a guardare il processo. Questo è tutto. Alcuni processi scelgono di chiudere in risposta, in genere perché il loro funzionamento non ha senso senza un terminale, alcuni scelgono di fare altre cose, come i file di configurazione di ricontrollo.

SIGKILL viene utilizzato per rimuovere con forza il processo dal kernel. E 'speciale, nel senso che non è in realtà un segnale al processo, ma piuttosto viene interpretato dal kernel direttamente.

Non inviare SIGKILL. SIGKILL dovrebbe certamente mai essere inviata per gli script. Se l'applicazione gestisce il SIGTERM, si può prendere un secondo per la pulizia, si può prendere un minuto, si può prendere un'ora . A seconda di ciò che l'applicazione deve ottenere fatto prima che sia pronto a porre fine. Qualsiasi logica che " si assume " Sequenza di pulizia di un'applicazione ha preso abbastanza a lungo e ha bisogno di essere collegamento o SIGKILLed dopo X secondi è semplicemente sbagliato .

L'unica ragione per cui la domanda sarebbe necessità un SIGKILL per terminare, è se qualcosa spiati durante la sua sequenza di pulizia. In questo caso è possibile aprire un terminale e SIGKILL manualmente. A parte questo, l'unica altra ragione per cui ci si SIGKILL qualcosa è perché desideri per evitare che si ripulire.

Anche se la metà del mondo manda ciecamente SIGKILL dopo 5 secondi è comunque cosa terribilmente sbagliata da fare.

Altri suggerimenti

Risposta breve:Inviare SIGTERM, 30 secondi dopo, SIGKILL.Cioè, invia SIGTERM, aspetta un po' (può variare da programma a programma, potresti conoscere meglio il tuo sistema, ma sono sufficienti da 5 a 30 secondi.Quando si spegne una macchina, è possibile vederla attendere automaticamente fino a 1'30 s.Perché tutta questa fretta?), quindi invia SIGKILL.

Risposta ragionevole: SIGTERM, SIGINT, SIGKILLQuesto è più che sufficiente.Il processo lo farà molto probabilmente terminare prima SIGKILL.

Risposta lunga: SIGTERM, SIGINT, SIGQUIT, SIGABRT, SIGKILL

Questo non è necessario, ma almeno non stai fuorviando il processo relativo al tuo messaggio.Tutti questi segnali Fare significa che vuoi che il processo interrompa ciò che sta facendo e esca.

Non importa quale risposta scegli da questa spiegazione, tienilo a mente!

Se invii un segnale che significa qualcos'altro, il processo può gestirlo in modi molto diversi (da un lato).D'altra parte, se il processo non gestisce il segnale, non importa cosa invii, il processo si chiuderà comunque (quando l'azione predefinita è terminare, ovviamente).

Quindi, devi pensare come te stesso come programmatore.Codificheresti un gestore di funzione per, diciamo, SIGHUP per uscire da un programma che si connette a qualcosa o lo metteresti in loop per provare a connetterti di nuovo?Questa è la domanda principale qui!Ecco perché è importante inviare solo segnali che significhino ciò che intendi.

Risposta lunga quasi stupida:

La tabella seguente contiene i segnali rilevanti e le azioni predefinite nel caso in cui il programma non li gestisca.

Li ho ordinati nell'ordine che suggerisco di utilizzare (a proposito, ti suggerisco di utilizzare il file risposta ragionevole, non questo qui), se proprio avete bisogno di provarli tutti (sarebbe divertente dire che la tabella è ordinata in termini di distruzione che potrebbero causare, ma non è così completamente VERO).

I segnali con un asterisco (*) lo sono NON consigliato.La cosa importante è che potresti non sapere mai per cosa è programmato.Appositamente SIGUSR!Potrebbe iniziare l'apocalisse (è un segnale gratuito affinché un programmatore faccia quello che vuole!).Ma, se non gestito O nell'improbabile caso in cui venga gestita la chiusura, il programma terminerà.

Nella tabella, i segnali con le opzioni predefinite per terminare e generare un core dump vengono lasciati alla fine, appena prima 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

Allora suggerirei questo risposta lunga quasi stupida: SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGQUIT, SIGABRT, SIGKILL

E infine, il

Risposta decisamente lunga e lunga decisamente stupida:

Non provarlo a casa.

SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGALRM, SIGUSR2, SIGUSR1, SIGQUIT, SIGABRT, SIGSEGV, SIGILL, SIGFPE e se nulla funzionasse, SIGKILL.

SIGUSR2 dovrebbe essere provato prima SIGUSR1 perché stiamo meglio se il programma non gestisce il segnale.Ed è molto più probabile che ce la faccia SIGUSR1 se ne gestisce solo uno.

A proposito, l'UCCISIONE:non è sbagliato inviare SIGKILL a un processo, come affermato in un'altra risposta.Bene, pensa cosa succede quando invii un file shutdown comando?Ci proverà SIGTERM E SIGKILL soltanto.Perché pensi che sia così?E perché hai bisogno di altri segnali, se proprio shutdown il comando usa solo questi due?


Ora, torniamo al risposta lunga, questa è una bella battuta:

for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done

Dorme per 30 secondi tra un segnale e l'altro.Perché altrimenti avresti bisogno di un oneliner? ;)

Inoltre, consigliato:provalo con solo segnali 15 2 9 dal risposta ragionevole.

sicurezza:togli il secondo echo quando sei pronto per partire.Lo chiamo mio dry-run per onliners.Usalo sempre per testare.


Script killgraziatamente

In realtà ero così incuriosito da questa domanda che ho deciso di creare una piccola sceneggiatura per fare proprio questo.Per favore, sentitevi liberi di scaricarlo (clonarlo) qui:

Collegamento GitHub a Repository Killgrafully

In genere devi inviare SIGTERM, il default di uccidere. E 'il valore predefinito per un motivo. Solo se un programma non fa l'arresto in un ragionevole lasso di tempo si dovrebbe ricorrere a SIGKILL. Ma nota che con SIGKILL il programma non ha alcuna possibilità di pulire le cose dati und potrebbe essere danneggiato.

Per quanto riguarda SIGHUP, HUP sta per "riagganciare" e storicamente ha fatto sì che il modem scollegato. E 'sostanzialmente equivalente a SIGTERM. La ragione per cui daemon volte usano SIGHUP riavviare o ricaricare configurazione è che daemon staccano i terminali di controllo come demone non necessita quelli e quindi sarebbe mai ricevere SIGHUP, in modo che il segnale è stato considerato come "liberato" per uso generale. Non tutti i demoni usano questo per ricarica! L'azione predefinita per SIGHUP è terminare e molti demoni si comportano in questo modo! Così non si può andare l'invio alla cieca SIGHUPs di demoni e in attesa di loro di sopravvivere.

Modifica SIGINT è probabilmente inadeguato per terminare un processo, come è normalmente legato a ^C o qualunque sia l'impostazione del terminale è quello di interrompere un programma. Molti programmi di cattura questo per i propri scopi, quindi è abbastanza comune per non funzionare. SIGQUIT ha tipicamente il default di creare un core dump, e se non si desidera che i file di base, che in giro non è un buon candidato, sia.

Sommario:. Se si invia SIGTERM e il programma non muore all'interno del vostro periodo di tempo poi inviarlo SIGKILL

SIGTERM in realtà significa l'invio di una richiesta di un messaggio: " potrebbe essere così gentile e suicidarsi ". Può essere intercettato e gestito mediante l'applicazione per eseguire la pulizia e lo spegnimento del codice.

SIGKILL non possono essere intrappolati da applicazione. Applicazione viene ucciso da OS senza alcuna possibilità per la pulizia.

E 'tipico di inviare SIGTERM prima, dormire un po' di tempo, quindi inviare SIGKILL.

  • SIGTERM è equivalente a "cliccando sul tasto 'X'" in una finestra.
  • SIGTERM è ciò che Linux utilizza un primo momento, quando si sta spegnendo.

Con tutta la discussione sta succedendo qui, nessun codice è stato offerto. Ecco il mio prendere:

#!/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 suona come spazzatura per me. Manderei per ottenere un demone di rileggere la sua configurazione.

SIGTERM può essere intercettato; i demoni appena potrebbe avere il codice di clean-up per eseguire quando riceve il segnale. Non si può farlo per SIGKILL. Così, con SIGKILL non stanno dando l'autore del demone di tutte le opzioni.

Più su quello su Wikipedia

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top