Como é que o SIGINT se relaciona com os outros sinais de terminação?

em sistemas POSIX, os sinais de terminação geralmente têm a seguinte ordem (de acordo com muitas páginas de manual e a Spec POSIX):

  1. SIGTERM-educadamente pedir um processo para terminar. Deve terminar graciosamente, limpando todos os recursos (arquivos, tomadas, processos infantis, etc.), apagando arquivos temporários e assim por diante.

  2. SIGQUIT-pedido mais forte. Ele vai acabar com a ingratidão, ainda limpando recursos que absolutamente precisam de limpeza, mas talvez não apagar arquivos temporários, talvez escrever informações de depuração em algum lugar; em algum sistema também será escrito um dump core (independentemente se o sinal é pego pelo aplicativo ou não).

  3. SIGKILL-pedido insistente. O processo nem sequer é pedido para fazer nada, mas o sistema vai limpar o processo, quer goste ou não. O mais provável é que tenha sido escrita uma lixeira.

Como é que o SIGINT se encaixa nessa imagem? Um processo CLI é normalmente terminado pelo SIGINT quando o utilizador hits CRTL+C, however a background process can also be terminated by SIGINT using KILL utility. O que não consigo ver nas especificações ou nos ficheiros de cabeçalho é se o SIGINT é mais ou menos forte do que o SIGTERM ou se existe alguma diferença entre o SIGINT e o SIGTERM.

actualizar:

a melhor descrição dos sinais de terminação que encontrei até agora está na documentação da GNU LibC . Explica muito bem que existe uma diferença entre SIGTERM e SIGQUIT.

Diz sobre SIGTERM:

é a forma normal de pedir educadamente a um programa para terminar.

E diz sobre SIGQUIT:

[...] e produz um dump do núcleo quando termina o processo, assim como um sinal de erro do programa. Você pode pensar nisto como uma condição de erro do programa "detectado" pelo Usuário. [...] Certos tipos de limpeza são melhor omitidos na manipulação SIGQUIT. Por exemplo, se o programa cria ficheiros temporários, deverá lidar com os outros pedidos de rescisão, eliminando o temporário arquivo. Mas é melhor para SIGQUIT não excluí-los, para que o usuário possa examiná - los em conjunção com a lixeira do núcleo.

E SIGHUP também é bem explicado. SIGHUP não é realmente um sinal de terminação, significa apenas que a" conexão " com o usuário foi perdida, de modo que o aplicativo não pode esperar que o usuário leia qualquer saída adicional (por exemplo, saída stdout/stderr) e não há nenhuma entrada a esperar do usuário qualquer mais. Para a maioria das aplicações, é melhor desistirem. Em teoria, um aplicativo também pode decidir que ele vai para o modo daemon quando um SIGHUP é recebido e agora é executado como um processo de fundo, escrevendo a saída para um arquivo de log configurado. Para a maioria dos daemons já em execução em segundo plano, SIGHUP geralmente significa que eles devem reexaminar seus arquivos de configuração, para que você enviá-lo para os processos de fundo após a edição de arquivos de configuração.

no entanto, não há nenhuma explicação útil de SIGINT nesta página, a não ser que ele é enviado pela CRTL+C. Há alguma razão para que alguém iria lidar com SIGINT de uma forma diferente do SIGTERM? Em caso afirmativo, qual seria a razão e como seria a manipulação diferente?

Author: Mecki, 2010-10-28

6 answers

Os pedidos de SIGTERM e SIGKILL destinam-se a fins gerais "terminar este processo". SIGTERM (por padrão) e SIGKILL (sempre) causarão a terminação do processo. SIGTERM pode ser pego pelo processo (por exemplo, para que ele possa fazer sua própria limpeza se quiser), ou até mesmo ignorado completamente; mas SIGKILL não pode ser pego ou ignorado.

SIGINT e SIGQUIT destinam-se especificamente a pedidos do terminal: podem ser atribuídos caracteres de entrada específicos para gerar estes sinais (dependendo da configuração de controlo do terminal). A ação padrão para SIGINT é o mesmo tipo de terminação do processo como a ação padrão para SIGTERM e a ação imutável para SIGKILL; a ação padrão para SIGQUIT também é terminação do processo, mas ações adicionais definidas pela implementação podem ocorrer, como a geração de um dump de núcleo. Tanto pode ser capturado ou ignorado pelo processo, se necessário.

O avistamento, como disse, tem a intenção de indicar que a ligação terminal tem perdeu-se, em vez de ser um sinal de terminação como tal. Mas, novamente, a ação padrão para SIGHUP (se o processo não pegar ou ignorá-lo) é terminar o processo da mesma forma que SIGTERM etc. .

Existe uma tabela nas definições de POSIX para signal.h que lista os vários sinais e as suas acções e objectivos predefinidos, e o capítulo da Interface de Terminal geral inclui muito mais detalhes sobre os sinais relacionados com o terminal.

 64
Author: Matthew Slattery, 2010-10-28 23:35:03

Como o 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) Eu vejo que os dois sinais são tratados da mesma forma, eles terminam o processo e são entregues a qualquer fio.

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */
 8
Author: Diomidis Spinellis, 2010-10-28 15:49:55

Depois de uma pesquisa rápida 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ê poderia, por exemplo, interceptar sigint e fazer algo especial com ele, sabendo que provavelmente foi enviado por um atalho de teclado. Talvez refresque a tela ou algo assim, em vez de morrer (Não recomendado, como as pessoas esperam ^C para matar o programa, apenas um exemplo).

Também aprendi que ^\ devia enviar sigquit, que posso começar a usar-me. Parece muito útil.

 7
Author: Jonathan, 2010-10-29 13:39:08

Alguns são ANSI C e outros não

Uma diferença considerável é que:

  • SIGINT e SIGTERM são ANSI C, portanto mais portáteis
  • SIGQUIT e SIGKILL não são

São descritos na secção "7.14 tratamento de sinais" do projecto n1256 de C99.:

  • SIGINT recebe um sinal de atenção interactivo
  • SIGTERM um pedido de cancelamento enviado para o programa
O que faz do SIGINT um bom candidato para um Interactive Ctrl + C.

Usando {[[0]} (tanto a chamada do sistema como o utilitário ' você pode enviar quase qualquer sinal para qualquer processo, dado que você tem a permissão. Um processo não pode distinguir como um sinal veio à vida e quem o Enviou.

Dito isto, SIGINT deve realmente cantar a interrupção do Ctrl-C, enquanto SIGTERM é o sinal geral do terminal. Não há conceito de um sinal ser "mais forte", com a única exceção de que existem sinais que não podem ser bloqueados ou manuseados (SIGKILL e SIGSTOP, de acordo com o man page).

Um sinal só pode ser "mais forte" do que outro sinal no que diz respeito a como um processo de recepção lida com o sinal (e qual é a ação padrão para esse sinal). Por exemplo, por padrão, SIGTERM e SIGINT levam à terminação. Mas se você ignorar SIGTERM, então ele não vai terminar o seu processo, enquanto SIGINT ainda faz.

 3
Author: DarkDust, 2010-10-28 11:23:19

Com Exceção de alguns sinais, os manipuladores de Sinais podem capturar os vários sinais, ou o comportamento padrão após a recepção de um sinal pode ser modificado. Veja a página do homem signal(7) para mais detalhes.

 0
Author: Ignacio Vazquez-Abrams, 2010-10-28 11:20:45