Die Antwort von @hvd ist grundsätzlich richtig. Um das noch mehr zu sichern, wird der init
Prozess zuerst SIGTERM
an Prozesse gesendet, SIGKILL
wenn Sie Ihren Computer herunterfahren, und wird dann nach einer Verzögerung gesendet, wenn sie noch nicht beendet wurden. Prozesse können nicht verarbeitet / ignoriert werden SIGKILL
.
Um ein bisschen mehr Details zu geben, ist die eigentliche Antwort, dass Sie nicht sicher wissen können, ob das Programm damit fertig wird. SIGTERM
ist das gebräuchlichste Signal, um ein Programm höflich zum Beenden aufzufordern, aber die gesamte Signalverarbeitung hängt davon ab, ob das Programm etwas mit dem Signal tut.
Anders ausgedrückt, basierend auf den anderen Antworten, wenn Sie ein Programm von @Jos oder @AlexGreg geschrieben hätten, dann wären sie vermutlich handhabbar, SIGQUIT
aber möglicherweise nicht SIGTERM
, und daher SIGTERM
wäre das Senden weniger "leise" als SIGQUIT
.
Ich habe einen Code geschrieben, mit dem Sie selbst herumspielen können. Speichern Sie das unten stehende als signal-test.c
, dann kompilieren Sie mit
gcc -o signal-test signal-test.c
Sie können es dann ausführen ./signal-test
und sehen, was passiert, wenn Sie verschiedene Signale mit senden killall -s <signal>
.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag = 0;
void handle_signal(int s)
{
flag = s;
}
int main(int argc, char *argv[])
{
signal(SIGTERM, handle_signal);
signal(SIGQUIT, handle_signal);
while(flag == 0){
sleep(1);
}
printf("flag is %d\n", flag);
return flag;
}
Der Code behandelt sowohl SIGTERM als auch SIGQUIT ordnungsgemäß. Sie können versuchen, die Zeilen zu kommentieren signal(SIG...
(mit einem //
am Zeilenanfang), um den Signal-Handler zu entfernen, und dann die Signale erneut ausführen und senden. Sie sollten in der Lage sein, diese verschiedenen Ausgaben zu sehen:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
je nachdem, ob Sie mit den Signalen umgehen oder nicht.
Sie können auch versuchen, die Signale zu ignorieren:
signal(SIGTERM, SIG_IGN);
Wenn Sie dies tun, führt das Senden zu SIGTERM
nichts, und Sie müssen SIGKILL
den Vorgang mit beenden.
Weitere Details in man 7 signal
. Beachten Sie, dass die Verwendung signal()
auf diese Weise als nicht portabel gilt - es ist jedoch viel einfacher als die Alternative!
Eine weitere kleine Fußnote zu Solaris killall
versucht, alle Prozesse abzubrechen. Alle von ihnen. Wenn Sie es als root ausführen, werden Sie überrascht sein :)