Em sistemas POSIX, os sinais de terminação geralmente têm a seguinte ordem (de acordo com muitas páginas MAN e as especificações POSIX):
SIGTERM - peça educadamente que um processo seja encerrado. Ele deve terminar normalmente, limpando todos os recursos (arquivos, soquetes, processos filho, etc.), excluindo arquivos temporários e assim por diante.
SIGQUIT - pedido mais forte. Ele deve terminar sem graça, ainda limpando recursos que absolutamente precisam de limpeza, mas talvez não exclua arquivos temporários, talvez escreva informações de depuração em algum lugar; em alguns sistemas também um dump de memória será gravado (independentemente se o sinal foi capturado pelo aplicativo ou não).
SIGKILL - pedido mais forte. O processo nem é solicitado a fazer nada, mas o sistema irá limpar o processo, quer goste ou não. Provavelmente, um dump de memória foi gravado.
Como o SIGINT se encaixa nessa imagem? Um processo CLI geralmente é encerrado por SIGINT quando o usuário pressiona CRTL + C, no entanto, um processo em segundo plano também pode ser encerrado por SIGINT usando o utilitário KILL. O que não consigo ver nas especificações ou nos arquivos de cabeçalho é se o SIGINT é mais ou menos forte do que o SIGTERM ou se há alguma diferença entre o SIGINT e o SIGTERM.
ATUALIZAR:
A melhor descrição dos sinais de término que encontrei até agora está na documentação GNU LibC . Isso explica muito bem que existe uma diferença pretendida entre SIGTERM e SIGQUIT.
Diz sobre SIGTERM:
É a maneira normal de pedir educadamente que um programa seja encerrado.
E diz sobre SIGQUIT:
e produz um core dump ao encerrar o processo, como um sinal de erro de programa. Você pode pensar nisso como uma condição de erro do programa “detectada” pelo usuário. [...] Certos tipos de limpeza são melhor omitidos no manuseio do SIGQUIT. Por exemplo, se o programa criar arquivos temporários, ele deve lidar com as outras solicitações de encerramento excluindo os arquivos temporários. Mas é melhor para o SIGQUIT não excluí-los, para que o usuário possa examiná-los em conjunto com o dump principal.
E SIGHUP também é explicado bem o suficiente. SIGHUP não é realmente um sinal de término, significa apenas que a "conexão" com o usuário foi perdida, então o aplicativo não pode esperar que o usuário leia mais nenhuma saída (por exemplo, saída stdout / stderr) e não há nenhuma entrada a esperar do usuário por mais tempo. Para a maioria dos aplicativos, isso significa que é melhor encerrar. Em teoria, um aplicativo também pode decidir que entra no modo daemon quando um SIGHUP é recebido e agora é executado como um processo em segundo plano, gravando a saída em um arquivo de log configurado. Para a maioria dos daemons já em execução em segundo plano, SIGHUP normalmente significa que eles devem reexaminar seus arquivos de configuração, portanto, você os envia para processos de segundo plano após editar os arquivos de configuração.
No entanto, não há nenhuma explicação útil do SIGINT nesta página, a não ser que ele é enviado por CRTL + C. Existe alguma razão pela qual alguém lidaria com o SIGINT de uma maneira diferente do SIGTERM? Em caso afirmativo, qual seria o motivo e como o tratamento seria diferente?
sudo fuser -l
em seu prompt de comando. Para mim, isso traz à tona:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
kill -l
uma lista de sinais.Respostas:
SIGTERM e SIGKILL destinam-se a solicitações de finalidades gerais de "encerramento deste processo". SIGTERM (por padrão) e SIGKILL (sempre) causarão o encerramento do processo. SIGTERM pode ser capturado pelo processo (por exemplo, para que ele possa fazer sua própria limpeza se quiser), ou até mesmo ser completamente ignorado; mas SIGKILL não pode ser capturado ou ignorado.
SIGINT e SIGQUIT destinam-se especificamente a solicitações do terminal: caracteres de entrada particulares podem ser atribuídos para gerar esses sinais (dependendo das configurações de controle do terminal). A ação padrão para SIGINT é o mesmo tipo de término de processo que a ação padrão para SIGTERM e a ação inalterável para SIGKILL; a ação padrão para SIGQUIT também é o término do processo, mas ações adicionais definidas pela implementação podem ocorrer, como a geração de um dump de memória. Ambos podem ser capturados ou ignorados pelo processo, se necessário.
SIGHUP, como você disse, destina-se a indicar que a conexão do terminal foi perdida, ao invés de ser um sinal de terminação como tal. Mas, novamente, a ação padrão para SIGHUP (se o processo não o capturar ou ignorar) é encerrar o processo da mesma forma que SIGTERM etc.
Há uma tabela nas definições POSIX para a
signal.h
qual lista os vários sinais e suas ações e propósitos padrão, e o capítulo Interface geral do terminal inclui muito mais detalhes sobre os sinais relacionados ao terminal.fonte
Como DarkDust observou, muitos sinais têm os mesmos resultados, mas os processos podem anexar diferentes ações a eles, distinguindo como cada sinal é gerado. Olhando para o código-fonte do kernel do FreeBSD (kern_sig.c), vejo que os dois sinais são tratados da mesma maneira, eles encerram o processo e são entregues a qualquer thread.
fonte
man 7 signal
Esta é a página de manual não normativa conveniente do projeto de páginas de manual do Linux que você frequentemente deseja consultar para obter informações de sinal do Linux.
A versão 3.22 menciona coisas interessantes como:
e contém a tabela:
que resume o sinal
Action
que distingue, por exemplo, SIGQUIT de SIGQUIT, uma vez que SIGQUIT tem açãoCore
e SIGINTTerm
.As ações são documentadas no mesmo documento:
Não consigo ver nenhuma diferença entre SIGTERM e SIGINT do ponto de vista do kernel, pois ambos têm ação
Term
e podem ser capturados. Parece que é apenas uma "distinção de convenção de uso comum":kill
Alguns sinais são ANSI C e outros não
Uma diferença considerável é que:
Eles são descritos na seção "7.14 Manuseio de sinais" do projeto C99 N1256 :
o que torna o SIGINT um bom candidato para um Ctrl + C interativo
POSIX 7
POSIX 7 documenta os sinais com o
signal.h
cabeçalho: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.htmlEsta página também tem a seguinte tabela de interesse que menciona algumas das coisas que já tínhamos visto em
man 7 signal
:BusyBox init
O
reboot
comando padrão 1.29.2 do BusyBox envia um SIGTERM para os processos, dorme por um segundo e, em seguida, envia o SIGKILL. Esta parece ser uma convenção comum em diferentes distros.Quando você desliga um sistema BusyBox com:
ele envia um sinal para o processo de inicialização.
Então, o manipulador de sinal init termina chamando:
que imprime no terminal:
Aqui está um exemplo concreto mínimo disso .
Sinais enviados pelo kernel
fonte
Após uma rápida pesquisa no Google por sigint vs sigterm , parece que a única diferença pretendida entre os dois é se foi iniciada por um atalho de teclado ou por uma chamada explícita para
kill
.Como resultado, você pode, por exemplo, interceptar sigint e fazer algo especial com ele, sabendo que provavelmente foi enviado por um atalho de teclado. Talvez atualize a tela ou algo assim, em vez de morrer (não recomendado, pois as pessoas esperam
^C
matar o programa, apenas um exemplo).Também aprendi que
^\
deve enviar sigquit, que posso começar a usar sozinho. Parece muito útil.fonte
Usando
kill
(tanto a chamada do sistema quanto o utilitário`, você pode enviar quase qualquer sinal para qualquer processo, desde que tenha permissão. Um processo não consegue distinguir como um sinal ganhou vida e quem o enviou.Dito isso, SIGINT realmente foi feito para marcar a interrupção Ctrl-C, enquanto SIGTERM é o sinal de terminal geral. Não existe o conceito de um sinal ser "mais forte", com a única exceção de que existem sinais que não podem ser bloqueados ou manipulados (SIGKILL e SIGSTOP, de acordo com a página de manual).
Um sinal só pode ser "mais forte" do que outro sinal no que diz respeito a como um processo de recebimento trata o sinal (e qual é a ação padrão para esse sinal). Por exemplo, por padrão, SIGTERM e SIGINT levam ao encerramento. Mas se você ignorar o SIGTERM, ele não encerrará o processo, enquanto o SIGINT ainda o faz.
fonte
Com exceção de alguns sinais, os manipuladores de sinal podem capturar os vários sinais, ou o comportamento padrão ao receber um sinal pode ser modificado. Veja a
signal(7)
página do manual para detalhes.fonte
SIGINT
sinal (“ interrupção do programa ”) é enviado quando o usuário digita o caractere INTR (normalmenteC-c
)." "SIGINT 2 Term Interrupt do teclado" Você pressiona Ctrl-C,SIGINT
é enviado. O processo normalmente morre. O que mais para dar?