Como o copy-on-write no fork () manipula o fork múltiplo?

17

Segundo a Wikipedia (o que pode estar errado)

When a fork() system call is issued, a copy of all the pages corresponding to the parent process is created, loaded into a separate memory location by the OS for the child process. But this is not needed in certain cases. Consider the case when a child executes an "exec" system call (which is used to execute any executable file from within a C program) or exits very soon after the fork(). When the child is needed just to execute a command for the parent process, there is no need for copying the parent process' pages, since exec replaces the address space of the process which invoked it with the command to be executed.

In such cases, a technique called copy-on-write (COW) is used. With this technique, when a fork occurs, the parent process's pages are not copied for the child process. Instead, the pages are shared between the child and the parent process. Whenever a process (parent or child) modifies a page, a separate copy of that particular page alone is made for that process (parent or child) which performed the modification. This process will then use the newly copied page rather than the shared one in all future references. The other process (the one which did not modify the shared page) continues to use the original copy of the page (which is now no longer shared). This technique is called copy-on-write since the page is copied when some process writes to it.

Parece que, quando um dos processos tenta gravar na página, uma nova cópia da página é alocada e atribuída ao processo que gerou a falha da página. A página original fica marcada como gravável posteriormente.

Minha pergunta é: o que acontece se o fork() for chamado várias vezes antes de qualquer um dos processos tentar escrever em uma página compartilhada?

    
por ssgao 11.12.2012 / 05:39

3 respostas

17

Nada em particular acontece. Todos os processos estão compartilhando o mesmo conjunto de páginas e cada um obtém sua própria cópia privada quando deseja modificar uma página.

    
por 11.12.2012 / 08:04
0

O comportamento de fork () depende se o sistema * nix tem uma MMU ou não. Em um sistema não-MMU (como os primeiros PDP-11s), a chamada do sistema fork () copiava toda a memória do pai para cada filho. Em um sistema * nix baseado em MMU, o kernel marca todas as páginas que não são de pilha como R / O e as compartilha entre pai e filho. Então, quando qualquer um dos processos grava em qualquer página, a MMU captura a tentativa, o kernel então aloca uma página gravável e atualiza as tabelas de páginas da MMU para apontar para a página agora gravável. Esse comportamento de cópia na gravação fornece uma aceleração, pois inicialmente apenas uma pilha particular precisa ser alocada e clonada para cada processo filho.

Se você executar algum código pai entre cada chamada fork (), os processos filhos resultantes serão diferentes pelas páginas que foram alteradas pelo pai. Por outro lado, se os pais simplesmente emitirem múltiplas chamadas fork (), por ex. em um loop, os processos filhos serão quase idênticos. Se uma variável de loop local for usada, isso será diferente na pilha de cada criança.

    
por 23.07.2018 / 14:19
-1

Quando o sistema pré-forma uma bifurcação, geralmente (isso pode depender da implementação), ele também marca as páginas como somente leitura e marca o processo pai como o mestre dessas páginas. Ao tentar gravar nessas páginas, ocorre uma falha de página e o SO assume o controle, copiando toda a lista de páginas ou apenas as alteradas (novamente, dependendo da implementação), portanto, o processo de gravação terá uma cópia gravável. Quando há vários processos bifurcados do mesmo, quando o processo "master" grava em sua memória, os processos outros obtêm suas páginas equivalentes copiadas.

    
por 11.12.2012 / 14:09

Tags