Sobes.tech
Middle

Ce se întâmplă cu memoria procesului atunci când creăm o copie a sa folosind apelul sistematic fork în sistemul de operare Linux?

sobes.tech AI

Răspuns de la AI

La apelarea fork(), nucleul sistemului de operare creează un nou proces, un proces fiu, care este aproape o copie exactă a procesului părinte.

Din punct de vedere al memoriei, se întâmplă următoarele:

  1. Spațiul de adresă virtuală: Procesul fiu primește propriul său spațiu de adresă virtuală separat, identic cu cel al părintelui la momentul apelului fork(). Aceasta înseamnă că procesul fiu "vede" aceleași intervale de adrese și are aceeași structură a segmentelor (cod, date, stivă, heap) ca și părinte.

  2. Memoria fizică și Copy-on-Write (CoW): Inițial, procesele părinte și fiu utilizează în comun aceleași pagini de memorie fizică. Aceasta este o optimizare cunoscută sub numele de "Copy-on-Write" (CoW). Memoria fizică este copiată doar atunci când unul dintre procese încearcă să modifice conținutul paginii.

    • Dacă procesul părinte sau fiu scrie date într-o pagină care anterior era comună, nucleul creează o copie nouă a acestei pagini de memorie fizică pentru procesul care scrie. Celălalt proces continuă să utilizeze versiunea veche a paginii.
    • Dacă procesele doar citesc date, continuă să utilizeze aceeași pagină de memorie fizică.
  3. Descriptori de fișiere: Descriptori de fișiere deschiși sunt moșteniți de procesul fiu. Ambele procese utilizează în comun indicatoare de offset în fișier.

  4. Alte resurse: Alte resurse, precum handler-ele de semnal, directorul de lucru curent etc., sunt, de asemenea, copiate sau moștenite.

Iată o ilustrație simplificată:

Înainte de fork():

+-------------------+
| Procesul părinte |
| +-----------------+ |
| | Memorie virtuală |
| | (Stivă, Heap, ...) |
| +-----------------+ |
|      |              |
|      V              |
| +-----------------+ |
| | Memorie fizică |
| +-----------------+ |
+-------------------+

Imediat după fork() (CoW):

+-----------------------+   +-----------------------+
| Procesul părinte      |   | Procesul fiu          |
| +-------------------+ |   | +-------------------+ |
| | Memorie virtuală  | |   | | Memorie virtuală  | |
| | (Aceeași structură)| |   | | (Aceeași structură)| |
| +-------------------+ |   | +-------------------+ |
|        |            |   |        |            |
|        V            |   |        V            |
| +-----------------------+   | +-----------------------+
| | Memorie fizică        | | | Memorie fizică        | |
| | (Unele pagini sunt comune)| | | (Unele pagini sunt comune)| |
| +-----------------------+   | +-----------------------+
+-----------------------+   +-----------------------+
          |                            |
          +----------------------------+
                Pagini inițiale comune de memorie fizică

După scrierea pe una dintre pagini (CoW activat):

+-----------------------+   +-----------------------+
| Procesul părinte      |   | Procesul fiu          |
| +-------------------+ |   | +-------------------+ |
| | Memorie virtuală  | |   | | Memorie virtuală  | |
| |                   | |   | |                   | |
| +-------------------+ |   | +-------------------+ |
|        |            |   |        |            |
|        V            |   |        V            |
| +-----------------------+   | +-----------------------+
| | Memorie fizică        | | | Memorie fizică        | |
| | (Pagini fizice separate)| | | (Pagini fizice separate)| |
| +-----------------------+   | +-----------------------+

Este important de înțeles că, în ciuda aceluiași spațiu de adresă virtuală imediat după fork(), orice modificare în memoria unui proces (scriere în variabile, alocare/eliberare de memorie în heap) nu afectează memoria celuilalt proces datorită mecanismului CoW. Aceasta sunt procese complet independente.