Então, eu sei que quando estou no shell e executo um executável, o shell o bifurca em um processo filho e, posteriormente, em executivos para obter o programa e a memória de dados do meu executável. Portanto, se meu shell estiver fechado/encerrado, todos os seus processos filhos associados também serão eliminados.
Eu li que no Linux todo processo é criado via fork() exec(). Estou curioso e queria saber sempre que um aplicativo é iniciado clicando duas vezes em seu ícone, qual processo forks() exec() ele, entendo que é algum processo do sistema operacional, queria saber qual
Obrigado!
Responder rastreou-o para /sbin/upstart
Responder1
Em primeiro lugar, um poucoterminologia.
Um executável é um arquivo simples em seu sistema. Um processo é o resumo que executa o programa incorporado em um arquivo executável.
Você está certo sobre omaneira como um arquivo executável é iniciado:
- O processo pai (já vivo)
fork
s em si, conduzindo em dois fluxos de execução a partir desse ponto. Um vivendo no processo pai e outro vivendo em um novo processo. - O novo processo (filho) silencia-se para executar o programa do executável a ser executado. Isto é feito usando umchamada de sistemado
exec
família.
Tomando o exemplo de uma interface gráfica na qual você clica duas vezes em um ícone executável, seu executável é bifurcado do processo mostrando o ícone em que você clicou basicamente com este código-fonte:
const char *exe_path = taken_from_icon();
int pid = fork();
if(pid == 0)
{
// I am the new child
execl(exe_path, exe_path, NULL);
// exec only return in case of failure
exit(EXIT_FAILURE);
}
// I am the graphical interface,
// Continue and wait for another clic
Mas omorte e paternidadeda criança não é exatamente como você diz.
Basicamente —e quando o processo pai ainda está vivo— o processo filho é filho de seu pai (sim!-). Ele tem seu PPID (ID do processo pai) definido para o processo ainda vivo que o bifurcou.
As coisas mudam quando o processo pai morre. O processo filho continua ativo, mas seu PPID está definido como um processo avó-pai ainda ativo. Sempre há um, já que init
o processo nunca morre.
O fato de as crianças com casca morrerem quando a própria casca morre é algo específico. Vejo duas razões para isso:
A primeira: um shell geralmente mantém uma lista de PIDs que ele bifurcou. E quando a casca morre, mata todos eles. Os principais shells têm um
disown
comando integrado para remover um filho desta lista e deixá-lo viver quando o shell morrer. Verpágina de manual do bash:O shell é encerrado por padrão após o recebimento de um SIGHUP. Antes de sair, um shell interativo reenvia o SIGHUP para todos os trabalhos, em execução ou parados. Os trabalhos interrompidos recebem SIGCONT para garantir que recebam o SIGHUP. Para evitar que o shell envie o sinal para um trabalho específico, ele deve ser removido da tabela de trabalhos com o disown embutido (veja COMANDOS BUILTIN DO SHELL abaixo) ou marcado para não receber SIGHUP usando disown -h.
A segunda: os filhos do shell geralmente têm seus stdin, stdout e stderr conectados ao próprio shell por meio de pipes. Se o shell parar de consumir o stdout filho (geralmente para imprimi-lo) ou fechar a extremidade do tubo, o filho poderá ter falhas ao gravar em seu stdout, o que pode bloqueá-lo ou eliminá-lo.