Como o kill por pgid afeta novos subprocessos?

2

Eu tenho um aplicativo muito complicado, que tem seu script de inicialização e o serviço principal executado como um daemon. Eu quero pará-lo rápido e graciosamente, então eu usei isso na função stop ():

group_id=$(ps -o pgid= $(cat $pidfile))
if [ ! -z $group_id ]; then
    kill -- -$group_id
success
fi

Envia sinal de terminação para todos os subprocessos / threads. Mas, e se alguns deles gerarem novos subprocessos? Parece que esses novos subprocessos não terminam seu trabalho, mas eu preciso. Se eu enviar o sinal de terminação para o daemon pai, todos os subprocessos terminam o trabalho com êxito, mas no shell ele mostra que o serviço já foi interrompido (veja meu tópico anterior - Como fazer o script de inicialização imprimir" OK "somente quando todos os subprocessos são interrompidos? ) Provavelmente, sinto falta de algo muito óbvio, mas ainda não sei como consertar isso com esforços mínimos. Por favor, dê algumas ideias pelo menos.

    
por Sergius 26.10.2015 / 20:50

1 resposta

1

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

    
por 27.10.2015 / 00:34