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?
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?
Respostas:
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 " init
se 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 init
processo vem para o resgate do processos órfãos e os adota. Isso significa que depois que uma criança perde seu pai, o init
processo se torna seu novo processo pai ".
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_SUBREAPER
opçã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_ACQUIRE
e PROC_REAP_RELEASE
opçõ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.
procctl()
. Páginas do manual do DragonFly BSD. § 2De acordo com a exit
pá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)
.
Eu não acredito nisso. Sempre vai para o processo de inicialização.