Por que um filho de um vfork ou fork deve chamar _exit () ao invés de exit ()?

11

Na página do manual de vfork() :

vfork() differs from fork() in that the parent is suspended until the child makes a call to execve(2) or _exit(2). The child shares all memory with its parent, including the stack, until execve() is issued by the child. The child must not return from the current function or call exit(), but may call _exit().

Por que o filho deve usar um _exit() em vez de simplesmente chamar exit() ? Espero que isso seja aplicável a vfork() e fork() .

    
por Sen 03.01.2011 / 15:45

4 respostas

10

Como visto anteriormente , vfork não permitir que o processo filho acesse a memória do pai. exit é uma função da biblioteca C (é por isso que é muito escrito como exit(3) ). Ele executa várias tarefas de limpeza, como liberação e fechamento de fluxos C (os arquivos abertos por meio de funções declaradas em stdio.h ) e a execução de funções especificadas pelo usuário registradas com atexit . Todas essas tarefas envolvem leitura e gravação na memória do processo.

_exit sai sem limpeza. É diretamente uma chamada de sistema (é por isso que é escrita como _exit(2) ), normalmente implementada colocando o número de chamada do sistema em um registrador de processador e executando uma instrução de processador específica (ramificando-se para o manipulador de chamada do sistema). Isso não precisa acessar a memória do processo, portanto, é seguro fazer isso depois de vfork .

Após fork , não existe tal restrição: o processo pai e filho agora são completamente autônomos.

    
por 03.01.2011 / 20:39
3

exit faz uma limpeza adicional como as funções de chamada registradas por atexit , portanto, acessa os dados fora da parte copiada. _exit executa syscall diretamente sem qualquer limpeza, exceto no kernel.

    
por 03.01.2011 / 16:43
2

Você tem a chamada filho _exit () para evitar a liberação de buffers stdio (ou outros) quando o processo filho é encerrado. Como o processo filho constitui uma cópia exata do processo pai, o processo filho ainda tem o que o pai tinha em "stdout" ou "stderr", os buffers de < stdio.h & gt ;. Você pode (e, em momentos inoportunos) obter saídas duplas chamando exit (), um dos manipuladores atexit do processo filho e um do pai, quando os buffers no processo pai ficam cheios e são liberados.

Eu percebo que a resposta acima se concentra nos detalhes do stdio.h, mas essa ideia provavelmente é transferida para outras E / S armazenadas em buffer, exatamente como uma das respostas acima indica.

    
por 03.01.2011 / 22:10
1

exit() : - executa alguma tarefa de limpeza, como fechar os fluxos de i / o e muitos, e depois retorna ao kernel. _exit() : - vem diretamente ao kernel (não executa nenhuma tarefa de limpeza).

fork() : pai e filho têm tabela de arquivos diferente, portanto, a mudança feita por filho não afeta os parâmetros de ambiente do pai e vice-versa.

vfork() : pai e filho usam a mesma tabela de arquivos, portanto, a alteração feita por filho afeta os parâmetros de ambiente do pai. por exemplo. alguma variável var=10 , agora execute var++ por filho e, em seguida, execute pai, você pode ver o efeito de var++ na saída do pai também.

Como eu disse, se você usar exit() em vfork() , todo o i / o já estará fechado. Portanto, mesmo que o pai seja executado corretamente, você não conseguirá obter a saída adequada, porque todas as variáveis são liberadas e todos os fluxos são fechados.

    
por 17.08.2013 / 17:49