Na página do manual de vfork()
:
vfork () difere de fork () porque o pai é suspenso até que o filho faça uma chamada para execve (2) ou _exit (2). O filho compartilha toda a memória com seu pai, incluindo a pilha, até execve () ser emitido pelo filho. O filho não deve retornar da função atual ou chamar exit (), mas pode chamar _exit ().
Por que a criança deveria usar um _exit()
chamado, em vez de simplesmente exit()
? Espero que isso seja aplicável a ambos vfork()
e fork()
.
c
system-calls
fork
exit
Sen
fonte
fonte
Respostas:
Como visto anteriormente ,
vfork
não permite que o processo filho acesse a memória dos pais.exit
é uma função da biblioteca C (é por isso que geralmente é escrita comoexit(3)
). Ele executa várias tarefas de limpeza, como liberação e fechamento de fluxos C (os arquivos são abertos por meio de funções declaradas emstdio.h
) e execução de funções especificadas pelo usuário registradasatexit
. Todas essas tarefas envolvem leitura e gravação na memória do processo._exit
sai sem limpeza. É diretamente uma chamada do sistema (e é por isso que está escrita como_exit(2)
), normalmente implementada colocando o número da chamada do sistema em um registro do processador e executando uma instrução específica do processador (ramificação para o manipulador de chamadas do sistema). Isso não precisa acessar a memória do processo, portanto é seguro fazê-lo depoisvfork
.Depois
fork
, não há essa restrição: o processo pai e filho agora são completamente autônomos.fonte
init
é bifurcado pelo kernel).exit
faça uma limpeza adicional, como chamar funções registradas e,atexit
portanto, acessar dados fora da parte copiada._exit
executa syscall diretamente sem qualquer limpeza, exceto no kernel.fonte
Você tem o filho chamado _exit () para evitar a descarga 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 possui o que o pai tinha em "stdout" ou "stderr", os buffers de <stdio.h>. Você pode (e, em momentos inoportunos) obter saídas duplas chamando exit (), uma dos manipuladores atexit do processo filho e uma do pai, quando os buffers no processo pai ficam cheios e são liberados.
Sei que a resposta acima se concentra nas especificidades do stdio.h, mas essa ideia provavelmente é transferida para outras E / S com buffer, exatamente como uma das respostas acima indica.
fonte
exit()
: - executa algumas tarefas de limpeza, como fechar os fluxos de E / S e muitos, e depois retorna ao kernel._exit()
: - chega diretamente ao kernel (não execute nenhuma tarefa de limpeza).fork()
: pai e filho têm uma tabela de arquivos diferente, portanto, as alterações feitas pelo filho não afetam 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 pelo filho afeta os parâmetros de ambiente do pai. por exemplo, alguma variávelvar=10
, agora executadavar++
por filho e, em seguida, execute pai, você também pode ver o efeitovar++
na saída do pai.Como eu disse, se você usar
exit()
emvfork()
seguida, toda a E / S já está fechado. Portanto, mesmo que o pai seja executado corretamente, você não poderá obter a saída adequada, porque todas as variáveis estão niveladas e todos os fluxos estão fechados.fonte