Системный вызов fork создает новый процесс, который является почти точной копией его родителя. Единственное различие двух процессов заключается только в необходимости отличать их друг от друга. После возврата из fork процесс-родитель и его потомок выполняют одну и ту же программу (функционирование которой продолжается сразу же вслед за fork) и имеют идентичные области данных и стека. Системный вызов fork во время своей работы должен совершить следующие действия:
• зарезервировать пространство свопинга для данных и стека процесса-потомка; • назначить новый идентификатор PID и структуру ргос потомка; • инициализировать структуру ргос потомка. Некоторые поля этой структуры копируются от процесса-родителя (такие как идентификаторы
С появлением современных много потоковых систем UNIX такая возможность больше не востребована: теперь сервер может иметь возможность создания необходимого количества нитей выполнения для токарного станка. пользователя и группы, маски сигналов и группа процесса), часть полей устанавливается в 0 (время нахождения в резидентном состоянии, использование процессора, канал сна и т. д.), а остальным присваиваются специфические для потомка значения (поля идентификаторов PID потомка и его родителя, указатель на структуру ргос родителя);
• разместить карты трансляции адресов для процесса-потомка; • выделить область и потомка и скопировать в нее содержимое области и процесса-родителя; • изменить ссылки области и на новые карты адресации и пространство допинга; • добавить потомка в набор процессов, разделяющих между собой область кода программы, выполняемой процессом-родителем; • постраничный дублировать области данных и стека родителя и модифицировать карты адресации потомка в соответствии этими новыми страницами; • получить ссылки на разделяемые ресурсы, наследуемые потомком, такие как открытые файлы и текущий рабочий каталог; • инициализировать аппаратный контекст потомка посредством копирования текущего состояния регистров его родителя; • сделать процесс-потомок выполняемым и поместить его в очередь планировщика; • установить для процесса-потомка по возврату из вызова fork нулевое значение; • вернуть идентификатор PID потомка его родителю.