As páginas de manual geralmente são documentos de referência concisos. A Wikipedia é um lugar melhor para obter explicações conceituais.
Fork duplica um processo: ele cria um processo filho quase idêntico ao processo pai (a diferença mais óbvia é que o novo processo tem um ID de processo diferente). Em particular, o fork (conceitualmente) deve copiar toda a memória do processo pai.
Como isso é bastante caro, o vfork foi inventado para lidar com um caso especial comum em que a cópia não é necessária. Freqüentemente, a primeira coisa que o processo filho faz é carregar uma nova imagem do programa, e é isso que acontece:
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
A execve
chamada carrega um novo programa executável e isso substitui o código do processo e a memória de dados pelo código do novo executável e uma nova memória de dados. Portanto, toda a cópia de memória criada por fork
foi inútil.
Assim, a vfork
ligação foi inventada. Não faz uma cópia da memória. Portanto, vfork
é barato, mas é difícil de usar, pois você precisa garantir que não acessa nenhum espaço de pilha ou pilha do processo no processo filho. Observe que mesmo a leitura pode ser um problema, porque o processo pai continua em execução. Por exemplo, esse código está quebrado (pode ou não funcionar, dependendo de o filho ou o pai obter uma fatia de tempo primeiro):
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
Desde a invenção do vfork, melhores otimizações foram inventadas. A maioria dos sistemas modernos, incluindo o Linux, usa uma forma de copiar na gravação , em que as páginas na memória do processo não são copiadas no momento da fork
chamada, mas mais tarde quando o pai ou o filho primeiro escreve na página. Ou seja, cada página começa como compartilhada e permanece compartilhada até que qualquer processo seja gravado nessa página; o processo que escreve obtém uma nova página física (com o mesmo endereço virtual). A cópia na gravação torna o vfork praticamente inútil, pois fork
não fará nenhuma cópia nos casos em vfork
que seria utilizável.
O Linux retém o vfork. A fork
chamada do sistema ainda deve fazer uma cópia da tabela de memória virtual do processo, mesmo se não copiar a memória real; vfork
nem precisa fazer isso. A melhoria de desempenho é insignificante na maioria dos aplicativos.
fork
precisa criar um mapeamento de memória virtual separado para que cópias subsequentes de cópia na gravação afetem apenas um dos dois processos.Os syscalls
fork()
evfork()
são diferentes.O
fork()
syscall gera dois processos idênticos com memória separada. Ovfork()
syscall gera dois processos que compartilham a mesma memória.Com
vfork()
o pai esperará que o filho termine. O pai herda das variáveis que o programa está compartilhando. Então, depois que o filho foi chamado, todas as variáveis modificadas dentro do filho ainda serão modificadas dentro do pai.Para mais informações clique aqui
fonte