Sobes.tech
Middle

Mi történik a folyamat memóriájával, amikor másolatát létrehozzuk a Linux operációs rendszerben a fork rendszerhívással?

sobes.tech MI

Válasz az MI-től

A fork() hívásakor az operációs rendszer kernelje létrehoz egy új folyamatot, egy gyermek folyamatot, amely szinte pontos másolata a szülő folyamatnak.

Memória szempontjából a következő történik:

  1. Virtuális címtér: A gyermek folyamat saját virtuális címtéröt kap, amely megegyezik a fork() hívás pillanatában a szülőével. Ez azt jelenti, hogy a gyermek "látja" ugyanazokat a címtartományokat, és ugyanaz a szegmensek (kód, adatok, verem, halom) struktúrája, mint a szülőé.

  2. Fizikai memória és Copy-on-Write (CoW): Kezdetben a szülő és a gyermek folyamat ugyanazokat a fizikai memória oldalakat használják. Ez egy optimalizáció, az úgynevezett "Copy-on-Write" (CoW). A fizikai memória csak akkor másolódik, amikor az egyik folyamat megpróbál módosítani egy oldalt.

    • Ha a szülő vagy a gyermek ír egy adatot egy olyan oldalra, amely korábban közös volt, a kernel létrehoz egy új példányt ennek az oldalnak a fizikai memóriában a író folyamat számára. A másik folyamat továbbra is a régi verziót használja.
    • Ha a folyamatok csak olvasnak adatokat, akkor továbbra is ugyanazt a fizikai memória oldalt használják.
  3. Fájl leírók: A megnyitott fájl leírók öröklődnek a gyermek folyamatba. Mindkét folyamat ugyanazokat a fájleltolás mutatókat használja.

  4. Egyéb erőforrások: Más erőforrások, például szignálkezelők, aktuális munkakönyvtár stb., szintén másolódnak vagy öröklődnek.

Íme egy leegyszerűsített ábra:

A fork() előtt:

+-------------------+
| Szülő folyamat |
| +-----------------+ |
| | Virtuális memória |
| | (Verem, Heap, ...) |
| +-----------------+ |
|      |              |
|      V              |
| +-----------------+ |
| | Fizikai memória |
| +-----------------+ |
+-------------------+

Azonnal a fork() után (CoW):

+-----------------------+   +-----------------------+
| Szülő folyamat       |   | Gyermek folyamat     |
| +-------------------+ |   | +-------------------+ |
| | Virtuális memória | |   | | Virtuális memória | |
| | (Ugyanaz a struktúra)| |   | | (Ugyanaz a struktúra)| |
| +-------------------+ |   | +-------------------+ |
|        |            |   |        |            |
|        V            |   |        V            |
| +-----------------------+   | +-----------------------+
| | Fizikai memória       | | | Fizikai memória       | |
| | (Néhány oldal közös)  | | | (Néhány oldal közös)  | |
| +-----------------------+   | +-----------------------+
+-----------------------+   +-----------------------+
          |                            |
          +----------------------------+
                Kezdeti fizikai oldal közös

Az egyik oldal írása után (CoW aktiválódik):

+-----------------------+   +-----------------------+
| Szülő folyamat       |   | Gyermek folyamat     |
| +-------------------+ |   | +-------------------+ |
| | Virtuális memória | |   | | Virtuális memória | |
| |                   | |   | |                   | |
| +-------------------+ |   | +-------------------+ |
|        |            |   |        |            |
|        V            |   |        V            |
| +-----------------------+   | +-----------------------+
| | Fizikai memória       | | | Fizikai memória       | |
| | (Független oldalakat tartalmaz)| | | (Független oldalakat tartalmaz)| |
| +-----------------------+   | +-----------------------+

Fontos megérteni, hogy annak ellenére, hogy az azonos virtuális címtér közvetlenül a fork() után, bármilyen változtatás a memória egyik folyamatban (változók írása, memória foglalása/felszabadítása a heap-ben) nem befolyásolja a másik folyamat memóriáját a CoW mechanizmusnak köszönhetően. Ezek teljesen független folyamatok.