Novo processo pai quando o processo pai morre

22

No UNIX, quando um processo pai desaparece, eu pensava que todos os processos filhos redefiniam o init como pai. Isso não está correto o tempo todo? Existem exceções?

user100503
fonte

Respostas:

5

Movendo meu comentário para uma resposta ... Não acredito que haja exceções.

Encontrou isso "às vezes o processo pai é morto antes que seu filho seja morto. Nesse caso, o processo" pai de todos os processos " initse torna o novo PPID (ID do processo pai). Às vezes, esses processos são chamados de processo órfão". fonte

Da mesma forma, é descrito no blog da IBM : "O pai morre ou é morto antes do filho. No cenário acima, o processo filho se torna o processo órfão (pois perdeu o pai). No Linux, o initprocesso vem para o resgate do processos órfãos e os adota. Isso significa que depois que uma criança perde seu pai, o initprocesso se torna seu novo processo pai ".

Simplesmente eu
fonte
61

Três respostas escritas em 2014, todas dizendo que no Unices e no Linux o processo é reparado no processo nº 1, sem exceção. Três respostas erradas. ☺

Como o SUS diz, citado em uma das outras respostas aqui, então não vou citá-lo novamente, o processo pai de filhos órfãos é definido como um processo definido pela implementação . Cristian Ciupitu está certo em consultar a documentação do Linux para ver o que a implementação define. Mas ele está sendo enganado por essa documentação, que é inconsistente e não atualizada.

Dois anos antes de essas três respostas serem escritas, e rapidamente, até três anos atrás, no momento em que escrevemos essa resposta, o kernel do Linux mudou. Os desenvolvedores do systemd adicionaram a capacidade dos processos de se configurarem como "sub-leitores". A partir do Linux 3.4, os processos em diante podem emitir a prctl()chamada do sistema com a PR_SET_CHILD_SUBREAPERopção e, como resultado, eles, e não o processo nº 1, se tornarão os pais de qualquer um dos processos descendentes órfãos. A página do manual paraprctl() está atualizada, mas outras páginas do manual não foram atualizadas e tornadas consistentes.

Na versão 10.2, FreeBSD ganhou a mesma capacidade, estendendo a sua já existente procctl()chamada de sistema com PROC_REAP_ACQUIREe PROC_REAP_RELEASEopções. Ele adotou esse mecanismo do DragonFly BSD; que ganhou na versão 4.2, originalmente nomeada, reapctl()mas renomeada durante o desenvolvimento para procctl().

Portanto, existem exceções e algumas bastante importantes: no Linux, FreeBSD / PC-BSD e DragonFly BSD, o processo pai de filhos órfãos é definido como o processo ancestral mais próximo do filho, marcado como subreader, ou processo # 1 se não houver processo de subreaper ancestral. Vários utilitários de supervisão de daemon - incluindo systemd (aquele cujos desenvolvedores colocam isso no kernel do Linux em primeiro lugar), iniciante e nosh service-manager- já fazem uso disso.

Se tal um supervisor daemon não é processar # 1, e ele gera um serviço como uma sessão de login interativo, e em que uma sessão faz o truque (bastante equivocada) de tentar "daemonize" por duas vezes fork()ing , então um do processo será acabar como filho do supervisor daemon, não do processo # 1. Esperar ser capaz de gerar daemons diretamente de dentro das sessões de logon é um erro fundamental, é claro. Mas essa é outra resposta.

Leitura adicional

JdeBP
fonte
Na verdade, eu notei processos órfãos sendo anexados a uma sessão init (no Ubuntu com Upstart), mas nunca percebi seu significado. +1
muru
Consulte unix.stackexchange.com/a/194208/5132 para obter mais informações sobre o inicio da sessão inicial, especificamente.
JdeBP
8

De acordo com a exitpágina do manual The Single UNIX® Specification, Versão 2:

O ID do processo pai de todos os processos filhos existentes e processos zumbis do processo de chamada é definido como o ID do processo de um processo do sistema dependente da implementação. Ou seja, esses processos são herdados por um processo especial do sistema.

Para a maioria das variantes do Unix, esse processo especial é init(PID 1).

A wait(2)página de manual do Linux confirma isso:

Se um processo pai terminar, seus filhos "zumbis" (se houver) são adotados pelo init (8), que executa automaticamente uma espera para remover os zumbis.

As páginas de manual do FreeBSD wait(2), NetBSD wait(2), OpenBSD wait(2)e Mac OS X wait(2)também confirmam isso:

Se um processo pai terminar sem aguardar o término de todos os processos filhos, os processos filhos restantes receberão o ID do processo pai 1 (o ID do processo init).

A wait(3C)página do manual Oracle Solaris 11.1 também confirma isso:

Se um processo pai terminar sem aguardar o término dos processos filhos, o ID do processo pai de cada processo filho será definido como 1, com o processo de inicialização herdando os processos filhos; veja Intro(2).

Cristian Ciupitu
fonte