La réponse de @hvd est fondamentalement correcte. Pour sauvegarder cela encore plus, le init
processus sera d'abord envoyé SIGTERM
aux processus lorsque vous éteignez votre ordinateur, puis après un délai sera envoyé SIGKILL
s'ils ne sont pas déjà sortis. Les processus ne peuvent pas gérer / ignorer SIGKILL
.
Pour donner un peu plus de détails, la vraie réponse est que vous n'avez aucun moyen de savoir avec certitude que le programme le gère. SIGTERM
est le signal le plus courant à utiliser pour demander poliment à un programme de quitter, mais tout traitement du signal dépend du programme qui fait quelque chose avec le signal.
Pour le dire différemment, sur la base des autres réponses, si vous aviez un programme écrit par @Jos ou par @AlexGreg, ils seraient probablement en train de gérer SIGQUIT
mais peut-être pas SIGTERM
, et donc l'envoi SIGTERM
serait moins "doux" que SIGQUIT
.
J'ai écrit du code pour que vous puissiez jouer avec lui-même. Enregistrez ci-dessous sous signal-test.c
, puis compilez avec
gcc -o signal-test signal-test.c
Vous pouvez ensuite l'exécuter ./signal-test
et voir ce qui se passe lorsque vous envoyez différents signaux avec 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;
}
En l'état, le code gère à la fois SIGTERM et SIGQUIT avec élégance. Vous pouvez essayer de commenter les lignes signal(SIG...
(en utilisant un //
au début de la ligne) pour supprimer le gestionnaire de signal, puis exécuter et envoyer à nouveau les signaux. Vous devriez pouvoir voir ces différentes sorties:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
selon que vous gérez ou non les signaux.
Vous pouvez également essayer d'ignorer les signaux:
signal(SIGTERM, SIG_IGN);
Si vous faites cela, l'envoi SIGTERM
ne fera rien, vous devrez utiliser SIGKILL
pour mettre fin au processus.
Plus de détails dans man 7 signal
. Notez que l'utilisation signal()
de cette manière est considérée comme non portable - c'est beaucoup plus facile que l'alternative!
Une autre note de bas de page mineure - sur Solaris killall
tente de tuer tous les processus. Tous. Si vous l'exécutez en tant que root, vous pourriez être surpris :)