Sobes.tech
Middle

Cosa succede alla memoria del processo quando ne creiamo una copia usando la chiamata di sistema fork nel sistema operativo Linux?

sobes.tech AI

Risposta dell'AI

Quando si chiama fork(), il kernel del sistema operativo crea un nuovo processo, un processo figlio, che è quasi una copia esatta del processo genitore.

Dal punto di vista della memoria, succede quanto segue:

  1. Spazio di indirizzi virtuali: Il processo figlio riceve il proprio spazio di indirizzi virtuali separato, identico a quello del genitore al momento della chiamata a fork(). Ciò significa che il processo figlio "vede" gli stessi intervalli di indirizzi e ha la stessa struttura di segmenti (codice, dati, stack, heap) del genitore.

  2. Memoria fisica e Copy-on-Write (CoW): Inizialmente, i processi genitore e figlio condividono le stesse pagine di memoria fisica. Questa è un'ottimizzazione nota come "Copy-on-Write" (CoW). La memoria fisica viene copiata solo quando uno dei processi tenta di modificare il contenuto di una pagina.

    • Se il processo genitore o figlio scrive dati in una pagina precedentemente condivisa, il kernel crea una nuova copia di quella pagina di memoria fisica per il processo che effettua la scrittura. L'altro processo continua a usare la versione vecchia della pagina.
    • Se i processi leggono solo, continuano a usare la stessa pagina di memoria fisica condivisa.
  3. Descrittori di file: I descrittori di file aperti vengono ereditati dal processo figlio. Entrambi i processi condividono i puntatori agli offset nel file.

  4. Altre risorse: Altre risorse, come i gestori di segnali, la directory di lavoro corrente, ecc., vengono anch'esse copiate o ereditate.

Ecco una rappresentazione semplificata:

Prima di fork():

+-------------------+
| Processo Padre    |
| +--------------+  |
| | Memoria Virtuale | |
| | (Stack, Heap, ...) | |
| +--------------+  |
|      |            |
|      V            |
| +--------------+  |
| | Memoria Fisica | |
| +--------------+  |
+-------------------+

Immediatamente dopo fork() (CoW):

+-----------------------+   +-----------------------+
| Processo Padre        |   | Processo Figlio       |
| +-------------------+ |   | +-------------------+ |
| | Memoria Virtual    | |   | | Memoria Virtual    | |
| | (La stessa struttura)| |   | | (La stessa struttura)| |
| +-------------------+ |   | +-------------------+ |
|        |              |   |        |              |
|        V              |   |        V              |
| +-------------------+ |   | +-------------------+ |
| | Memoria Fisica     | |   | | Memoria Fisica     | |
| | (Alcune pagine condivise)| | | (Alcune pagine condivise)| |
| +-------------------+ |   | +-------------------+ |
+-----------------------+   +-----------------------+
          |                            |
          +----------------------------+
                Pagine fisiche iniziali condivise

Dopo aver scritto in una delle pagine (CoW attivato):

+-----------------------+   +-----------------------+
| Processo Padre        |   | Processo Figlio       |
| +-------------------+ |   | +-------------------+ |
| | Memoria Virtuale    | |   | | Memoria Virtuale    | |
| |                   | |   | |                   | |
| +-------------------+ |   | +-------------------+ |
|        |              |   |        |              |
|        V              |   |        V              |
| +-------------------+ |   | +-------------------+ |
| | Memoria Fisica     | |   | | Memoria Fisica     | |
| | (Pagine fisiche separate)| | | (Pagine fisiche separate)| |
| +-------------------+ |   | +-------------------+ |
+-----------------------+   +-----------------------+

È importante capire che, anche se immediatamente dopo fork() lo spazio di indirizzi virtuali è identico, ogni modifica alla memoria di un processo (scrittura in variabili, allocazione/liberazione di memoria nel heap) non influisce sulla memoria dell'altro processo grazie al meccanismo CoW. Sono processi completamente indipendenti.