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):
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.
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).
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.
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:E diz sobre SIGQUIT:é a forma normal de pedir educadamente a um programa para terminar.
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.[...] 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.
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?
6 answers
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.
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 */
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
.
^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.
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
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.
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.