Sobes.tech
Middle

Какво се случва с паметта на процеса, когато създаваме негово копие с помощта на системния повик fork в операционната система Linux?

sobes.tech AI

Отговор от AI

При извикване на fork(), ядрото на операционната система създава нов процес, дъщерен процес, който е почти точно копие на родителския процес.

От гледна точка на паметта, се случва следното:

  1. Виртуално адресно пространство: Дъщерният процес получава собствено виртуално адресно пространство, което е идентично с това на родителя в момента на извикването на fork(). Това означава, че дъщерният процес "вижда" същите диапазони от адреси и има същата структура на сегментите (код, данни, стек, купчина), както и родителят.

  2. Физическа памет и Copy-on-Write (CoW): П initially, родителският и дъщерният процес споделят едни и същи страници от физическата памет. Това е оптимизация, известна като "Copy-on-Write" (CoW). Физическата памет се копира само когато един от процесите се опита да промени съдържанието на страница.

    • Ако родителският или дъщерният процес запише данни в страница, която по-рано е била обща, ядро създава нова копие на тази страница за процеса, който пише. Другият процес продължава да използва старата версия.
    • Ако процесите само четат данни, те продължават да използват общата страница.
  3. Файлови дескриптори: Отворените файлови дескриптори се наследяват от дъщерния процес. И двата процеса споделят указатели за отместване в файла.

  4. Други ресурси: Други ресурси, като обработчици на сигнали, текуща работна директория и т.н., също се копират или наследяват.

Ето опростена илюстрация:

Преди fork():

+-------------------+
| Родителски процес |
| +-----------------+ |
| | Виртуална памет |
| | (Стек, Купчина, ...) |
| +-----------------+ |
|      |              |
|      V              |
| +-----------------+ |
| | Физическа памет |
| +-----------------+ |
+-------------------+

Непосредствено след fork() (CoW):

+-----------------------+   +-----------------------+
| Родителски процес     |   |  Дъщерен процес     |
| +-------------------+ |   | +-------------------+ |
| | Виртуална памет  | |   | | Виртуална памет  | |
| | (Структурата е същата)| |   | | (Структурата е същата)| |
| +-------------------+ |   | +-------------------+ |
|        |                |   |        |                |
|        V                |   |        V                |
| +-----------------------+   | +-----------------------+
| | Физическа памет        | | | Физическа памет        | |
| | (Някои страници са общи)| | | (Някои страници са общи)| |
| +-----------------------+   | +-----------------------+
+-----------------------+   +-----------------------+
          |                            |
          +----------------------------+
                Начални страници на физическата памет са общи

След запис върху една от страниците (активиране на CoW):

+-----------------------+   +-----------------------+
| Родителски процес     |   |  Дъщерен процес     |
| +-------------------+ |   | +-------------------+ |
| | Виртуална памет  | |   | | Виртуална памет  | |
| | (Страници са отделни)| |   | | (Страници са отделни)| |
| +-------------------+ |   | +-------------------+ |
|        |                |   |        |                |
|        V                |   |        V                |
| +-----------------------+   | +-----------------------+
| | Физическа памет        | | | Физическа памет        | |
| | (Отделни страници)    | | | (Отделни страници)    | |
| +-----------------------+   | +-----------------------+

Важно е да разберем, че въпреки че веднага след fork() виртуалното адресно пространство е едно и също, всяка промяна в паметта на един процес (писане в променливи, разпределяне/освобождаване на памет в купчината) не влияе върху паметта на другия процес благодарение на механизма CoW. Това са напълно независими процеси.