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