Matar por ID do grupo de processos é atômico. Um processo não escapará ao entrar na hora errada. Para esse propósito, você pode tratar kill
, fork
e setpgid
como operações atômicas que são executadas em ordem. Se um processo for if (!fork()) setpgid()
, o filho será eliminado se kill
for executado após fork
, mas antes de setpgid
.
It seems like these new subprocesses don't finish their job
Todos os subprocessos recebem o sinal. Esse é o ponto dos grupos de processos.
If I send terminate signal to parent daemon, all subprocessess finish their job successfully, but in shell it shows that service has been already stopped
Isso é esperado. Na verdade, kill
retorna para o script antes mesmo que o processo seja interrompido: o processo de destino pode estar atualmente bloqueando os sinais. Em uma máquina multiprocessada, você pode observar o processo eliminado fazendo algo após kill -9
ter retornado.
Se o script de shell estiver verificando se o processo mestre morreu, isso significa apenas que o processo mestre morreu. Não há como esperar que um processo ou grupo de processos morra, exceto pelo pai do processo ou líder do grupo de processos. Não há nenhuma maneira conveniente de verificar se todos os processos em um grupo de processos morreram se você não configurasse nada ao iniciar o processo mestre.
A maneira normal de lidar com tais situações é ter um comando acelerador em seu daemon, que faz com que ele seja encerrado de forma limpa (incluindo a manipulação de qualquer trabalho feito por subprocessos) e só relata que o desligamento está completo e sai. Veja o Apache HTTPD por exemplo.
Como alternativa, você pode detectar a árvore de processos se você se preparar antecipadamente. Consulte Como obter o pid para o último aplicativo de plano de fundo