Какво се случва с паметта на процеса, когато създаваме негово копие с помощта на системния повик fork в операционната система Linux?
sobes.tech AI
Отговор от AI
При извикване на fork(), ядрото на операционната система създава нов процес, дъщерен процес, който е почти точно копие на родителския процес.
От гледна точка на паметта, се случва следното:
-
Виртуално адресно пространство: Дъщерният процес получава собствено виртуално адресно пространство, което е идентично с това на родителя в момента на извикването на
fork(). Това означава, че дъщерният процес "вижда" същите диапазони от адреси и има същата структура на сегментите (код, данни, стек, купчина), както и родителят. -
Физическа памет и Copy-on-Write (CoW): П initially, родителският и дъщерният процес споделят едни и същи страници от физическата памет. Това е оптимизация, известна като "Copy-on-Write" (CoW). Физическата памет се копира само когато един от процесите се опита да промени съдържанието на страница.
- Ако родителският или дъщерният процес запише данни в страница, която по-рано е била обща, ядро създава нова копие на тази страница за процеса, който пише. Другият процес продължава да използва старата версия.
- Ако процесите само четат данни, те продължават да използват общата страница.
-
Файлови дескриптори: Отворените файлови дескриптори се наследяват от дъщерния процес. И двата процеса споделят указатели за отместване в файла.
-
Други ресурси: Други ресурси, като обработчици на сигнали, текуща работна директория и т.н., също се копират или наследяват.
Ето опростена илюстрация:
Преди fork():
+-------------------+
| Родителски процес |
| +-----------------+ |
| | Виртуална памет |
| | (Стек, Купчина, ...) |
| +-----------------+ |
| | |
| V |
| +-----------------+ |
| | Физическа памет |
| +-----------------+ |
+-------------------+
Непосредствено след fork() (CoW):
+-----------------------+ +-----------------------+
| Родителски процес | | Дъщерен процес |
| +-------------------+ | | +-------------------+ |
| | Виртуална памет | | | | Виртуална памет | |
| | (Структурата е същата)| | | | (Структурата е същата)| |
| +-------------------+ | | +-------------------+ |
| | | | | |
| V | | V |
| +-----------------------+ | +-----------------------+
| | Физическа памет | | | Физическа памет | |
| | (Някои страници са общи)| | | (Някои страници са общи)| |
| +-----------------------+ | +-----------------------+
+-----------------------+ +-----------------------+
| |
+----------------------------+
Начални страници на физическата памет са общи
След запис върху една от страниците (активиране на CoW):
+-----------------------+ +-----------------------+
| Родителски процес | | Дъщерен процес |
| +-------------------+ | | +-------------------+ |
| | Виртуална памет | | | | Виртуална памет | |
| | (Страници са отделни)| | | | (Страници са отделни)| |
| +-------------------+ | | +-------------------+ |
| | | | | |
| V | | V |
| +-----------------------+ | +-----------------------+
| | Физическа памет | | | Физическа памет | |
| | (Отделни страници) | | | (Отделни страници) | |
| +-----------------------+ | +-----------------------+
Важно е да разберем, че въпреки че веднага след fork() виртуалното адресно пространство е едно и също, всяка промяна в паметта на един процес (писане в променливи, разпределяне/освобождаване на памет в купчината) не влияе върху паметта на другия процес благодарение на механизма CoW. Това са напълно независими процеси.