O que acontece com a memória do processo quando criamos uma cópia dele usando a chamada de sistema fork no sistema operativo Linux?
sobes.tech IA
Resposta da IA
Ao chamar fork(), o núcleo do sistema operativo cria um novo processo, um processo filho, que é quase uma cópia exata do processo pai.
Do ponto de vista da memória, o seguinte acontece:
-
Espaço de endereços virtuais: O processo filho recebe o seu próprio espaço de endereços virtuais separado, idêntico ao do pai no momento da chamada a
fork(). Isso significa que o processo filho "vê" os mesmos intervalos de endereços e tem a mesma estrutura de segmentos (código, dados, pilha, heap) que o pai. -
Memória física e Copy-on-Write (CoW): Inicialmente, os processos pai e filho partilham as mesmas páginas de memória física. Esta é uma otimização conhecida como "Copy-on-Write" (CoW). A memória física só é copiada quando um dos processos tenta alterar o conteúdo de uma página.
- Se o processo pai ou filho escreve dados numa página que anteriormente era partilhada, o núcleo cria uma nova cópia dessa página de memória física para o processo que faz a escrita. O outro processo continua a usar a versão antiga da página.
- Se os processos apenas leem dados, continuam a usar a mesma página de memória física partilhada.
-
Descritores de ficheiros: Os descritores de ficheiros abertos são herdados pelo processo filho. Ambos os processos partilham os ponteiros para os deslocamentos no ficheiro.
-
Outros recursos: Outros recursos, como manipuladores de sinais, diretório de trabalho atual, etc., também são copiados ou herdados.
Aqui uma ilustração simplificada:
Antes de fork():
+-------------------+
| Processo Pai |
| +--------------+ |
| | Memória Virtual | |
| | (Pilha, Heap, ...) | |
| +--------------+ |
| | |
| V |
| +--------------+ |
| | Memória Física | |
| +--------------+ |
+-------------------+
Imediatamente após fork() (CoW):
+-----------------------+ +-----------------------+
| Processo Pai | | Processo Filho |
| +-------------------+ | | +-------------------+ |
| | Memória Virtual | | | | Memória Virtual | |
| | (A mesma estrutura)| | | | (A mesma estrutura)| |
| +-------------------+ | | +-------------------+ |
| | | | | |
| V | | V |
| +-------------------+ | | +-------------------+ |
| | Memória Física | | | | Memória Física | |
| | (Algumas páginas partilhadas)| | | (Algumas páginas partilhadas)| |
| +-------------------+ | | +-------------------+ |
+-----------------------+ +-----------------------+
| |
+----------------------------+
Páginas físicas iniciais partilhadas
Após modificar uma página (CoW ativado):
+-----------------------+ +-----------------------+
| Processo Pai | | Processo Filho |
| +-------------------+ | | +-------------------+ |
| | Memória Virtual | | | | Memória Virtual | |
| | | | | | | |
| +-------------------+ | | +-------------------+ |
| | | | | |
| V | | V |
| +-------------------+ | | +-------------------+ |
| | Memória Física | | | | Memória Física | |
| | (Páginas físicas separadas)| | | (Páginas físicas separadas)| |
| +-------------------+ | | +-------------------+ |
+-----------------------+ +-----------------------+
É importante entender que, embora o espaço de endereços virtuais seja idêntico imediatamente após fork(), quaisquer alterações na memória de um processo (escrever em variáveis, alocar/libertar memória no heap) não afetam a memória do outro processo graças ao mecanismo CoW. São processos completamente independentes.