
Já vi muitos gerentes de processos que tentam fazer isso. Entendo que você só deveria usar SIGTERM para encerrar um processo. O processo pode levar um tempo desconhecido para ser limpo; em um sistema lento, pode levar alguns minutos. Sempre pensei que a única solução era ser paciente e esperar que o programa fosse limpo e encerrado normalmente. Se o processo não capturar os SIGTERMs, isso é um bug e deve ser relatado ao mantenedor do software.
Já vi ferramentas populares como o docker também tentando fazer isso:
Uso: docker stop [OPÇÕES] CONTAINER [CONTAINER...]
Pare um contêiner em execução (envie SIGTERM e, em seguida, SIGKILL após o período de carência)
Isso é uma má prática? Uma coisa que também estou curioso é como o procedimento de desligamento funciona em um sistema init estilo SystemV. Dei uma olhada em algumas páginas de manual e outras perguntas, mas não consigo encontrar uma resposta definitiva. Suponho que cada serviço de inicialização (terminologia?) Vê a mudança no nível de execução e executa a função "parar" adequada, conforme definido no script de inicialização. Ele faz isso um por um, garantindo que cada serviço termine corretamente? O que acontece com os processos não controlados pelos scripts de inicialização? Já vi algumas perguntas mencionarem vagamente um período de carência antes de SIGKILLá-las, mas esperava que alguém pudesse elaborar ou pelo menos me indicar a direção certa. :)
Se alguém pudesse me ajudar a descobrir mais sobre como isso funciona com o systemd também, ficarei feliz em pesquisar e descobrir mais. Dei uma olhada nas páginas de manual, mas também não consegui encontrar nada definitivo aqui.
Responder1
Você pode pegar seu bolo ou comê-lo. O programa quer ter o tempo que precisar (ou quiser) para reagir ao SIGTERM. O sistema (gerente de programa) deseja encerrar. Se o sistema esperar para sempre, isso permitirá que um programa sequestre o desligamento do sistema, nunca respondendo (seja porque o programa é malicioso ou porque tem bugs).
Em uma sequência de desligamento normal, cada daemon é finalizado através de um script de inicialização (chame-o de script de desligamento se desejar) fornecido pelo autor ou empacotador do daemon. Dependendo do daemon, o script init pode apenas enviar um sinal ou pode fazer um desligamento mais controlado (por exemplo, escrevendo em um soquete). O script de inicialização pode esperar que o daemon relate que foi encerrado satisfatoriamente ou pode eliminá-lo à força. Os scripts de inicialização são executados como root (eles podem chamar su
para executar parte de sua tarefa como um usuário menos privilegiado); eles deveriam ser cooperativos, então podem deixar o sistema suspenso para sempre.
Depois que os scripts de inicialização terminarem seu trabalho, todos os serviços deverão ser encerrados. Qualquer processo restante deve ser considerado sem importância ou com comportamento inadequado. Portanto, neste estágio, os processos restantes são instruídos a desligar (SIGTERM) e, após um período de carência (dando-lhes uma última chance de desligar corretamente), o sistema deve ser desligado para que todos os processos restantes sejam eliminados à força (SIGKILL).
Pense nos scripts de inicialização como o procedimento normal de prisão - mostre mandados, grite um aviso, etc. Um daemon cumpridor da lei deve encerrar neste ponto, embora os daemons tenham advogados (os scripts de inicialização) que podem atrasar o procedimento, desde que eles querer. Uma vez concluído o processo normal, os daemons restantes são considerados hostis. O sistema dispara um tiro de advertência (SIGTERM) e, após um atraso, dispara para SIGKILL.