A resposta do @hvd está basicamente correta. Para dar ainda mais suporte, o init
processo será enviado primeiro SIGTERM
aos processos quando você estiver desligando o computador e depois de um atraso será enviado SIGKILL
se eles ainda não tiverem saído. Os processos não podem manipular / ignorar SIGKILL
.
Para dar um pouco mais de detalhes, a resposta real é que você não tem como saber com certeza que o programa lida com isso. SIGTERM
é o sinal mais comum a ser usado para pedir educadamente a um programa para sair, mas toda a manipulação de sinais depende do programa fazer algo com o sinal.
Em outras palavras, com base nas outras respostas, se você tivesse um programa escrito por @Jos ou por @AlexGreg, eles provavelmente estariam lidando com, SIGQUIT
mas possivelmente não SIGTERM
, e, portanto, o envio SIGTERM
seria menos "suave" do que SIGQUIT
.
Eu escrevi um código para que você possa brincar com ele. Salve o abaixo como signal-test.c
e compile com
gcc -o signal-test signal-test.c
Você pode executá-lo ./signal-test
e ver o que acontece quando envia sinais diferentes com 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;
}
Tal como está, o código lida com SIGTERM e SIGQUIT normalmente. Você pode tentar comentar as linhas signal(SIG...
(usando a //
no início da linha) para remover o manipulador de sinais, executar e enviar os sinais novamente. Você poderá ver essas diferentes saídas:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
dependendo se você lida com os sinais ou não.
Você também pode tentar ignorar os sinais:
signal(SIGTERM, SIG_IGN);
Se você fizer isso, o envio SIGTERM
não fará nada, você precisará usar SIGKILL
para finalizar o processo.
Mais detalhes em man 7 signal
. Observe que o uso signal()
dessa maneira é considerado não portátil - é muito mais fácil do que a alternativa!
Uma outra nota de rodapé menor - no Solaris, killall
tenta matar todos os processos. Todos eles. Se você executá-lo como root, poderá se surpreender :)