Введение

В вычислительной технике операция, при которой процесс создает копию самого себя. В вычислительной технике, особенно в контексте операционной системы Unix и её аналогов, fork – это операция, посредством которой процесс создает копию самого себя. Это интерфейс, необходимый для соответствия стандартам POSIX и Single UNIX Specification. Обычно он реализован как обертка стандартной библиотеки C вокруг системных вызовов ядра fork, clone или других подобных вызовов. Fork является основным методом создания процессов в Unix-подобных операционных системах.

Обзор

В многозадачных операционных системах процессам (запущенным программам) необходим способ создания новых процессов, например, для запуска других программ. Механизм fork и его варианты обычно являются единственным способом сделать это в Unix-подобных системах. Чтобы процесс начал выполнение другой программы, он сначала использует fork для создания своей копии. Затем эта копия, называемая "дочерним процессом", вызывает системный вызов exec для замены себя другой программой: она прекращает выполнение своей исходной программы в пользу новой. Операция fork создает отдельное адресное пространство для дочернего процесса. Дочерний процесс получает точную копию всех сегментов памяти родительского процесса. В современных вариантах UNIX, использующих модель виртуальной памяти, разработанную в SunOS 4.0, реализована семантика copy-on-write, и физическая память не обязательно копируется. Вместо этого, страницы виртуальной памяти в обоих процессах могут ссылаться на одни и те же страницы физической памяти до тех пор, пока один из процессов не попытается прочитать такую страницу: в этом случае страница копируется. Эта оптимизация особенно важна, когда fork используется совместно с exec для запуска новой программы: обычно дочерний процесс выполняет лишь небольшое количество операций, прежде чем прекратить выполнение своей программы в пользу запускаемой программы, и ему требуется очень мало, если вообще требуется, структур данных родительского процесса. Когда процесс вызывает fork, он становится родительским процессом, а вновь созданный процесс – его дочерним. После fork оба процесса не только начинают выполнять одну и ту же программу, но и продолжают выполнение, как если бы оба вызвали системный вызов. Затем они могут проверить возвращаемое значение системного вызова, чтобы определить свой статус – родительский или дочерний – и действовать соответствующим образом.

История

Одно из самых ранних упоминаний концепции `fork` появилось в книге «A Multiprocessor System Design» Мелвина Конвея, опубликованной в 1962 году. Статья Конвея послужила стимулом для реализации `fork` Л. Питером Дойчем в системе совместного использования времени GENIE, где Кен Томпсон позаимствовал эту концепцию для её первого появления в Research Unix. Впоследствии `fork` стал стандартным интерфейсом в POSIX.

Сообщение

Дочерний процесс запускается с копией файловых дескрипторов родительского процесса. Для межпроцессного взаимодействия родительский процесс часто создает одну или несколько каналов, а затем, после создания дочернего процесса, каждый процесс закрывает те концы каналов, которые ему не требуются.

Вилка

Vfork — это вариант функции fork с той же конвенцией вызова и почти идентичной семантикой, но предназначенный для использования только в ограниченных ситуациях. Он появился в версии Unix 3BSD, первой Unix-системе, поддерживающей виртуальную память. Vfork был стандартизирован POSIX, что допускало его идентичное поведение с fork, однако в редакции 2004 года он был признан устаревшим и в последующих редакциях заменен на posix spawn (который обычно реализуется с использованием vfork). При вызове системной функции vfork родительский процесс приостанавливается до тех пор, пока дочерний процесс не завершит выполнение или не будет заменен новым исполняемым образом посредством одной из функций семейства "exec". Дочерний процесс использует настройки блока управления памятью родительского процесса, а страницы памяти совместно используются родительским и дочерним процессами без копирования, в частности, без использования механизма copy-on-write.

Аналогично, руководство пользователя Linux для vfork настоятельно не рекомендует его использование, однако спецификация POSIX отмечает, что он был разработан как операция ядра, особенно для операционных систем, работающих на ограниченном оборудовании и в системах реального времени. В то время как реализация 4.4BSD отказалась от реализации vfork, в результате чего vfork стал вести себя как fork, позже он был восстановлен в операционной системе NetBSD по соображениям производительности. Некоторые встраиваемые операционные системы, такие как uClinux, исключают fork и реализуют только vfork, поскольку им необходимо работать на устройствах, где copy-on-write невозможно реализовать из-за отсутствия блока управления памятью.

Вилка

Операционная система Plan 9, созданная разработчиками Unix, включает в себя `fork`, а также вариант с названием `rfork`, который обеспечивает детальное разделение ресурсов между родительским и дочерним процессами, включая адресное пространство (за исключением сегмента стека, который уникален для каждого процесса), переменные окружения и пространство имен файловой системы. Это делает его единым интерфейсом для создания как процессов, так и потоков внутри них. И FreeBSD, и IRIX переняли системный вызов `rfork` из Plan 9, при этом IRIX переименовала его в `sproc`.

Клон

clone — это системный вызов в ядре Linux, который создает дочерний процесс, способный разделять части своего контекста исполнения с родительским процессом. Подобно rfork в FreeBSD и sproc в IRIX, Linux clone был вдохновлен rfork в Plan 9 и может использоваться для реализации потоков (хотя разработчики приложений обычно используют интерфейс более высокого уровня, такой как pthreads, реализованный на основе clone). Функция раздельных стеков из Plan 9 и IRIX была опущена, поскольку (по мнению Линуса Торвальдса) она создает излишнюю нагрузку.

Форкинг в других операционных системах

В первоначальной конструкции операционной системы VMS (1977 г.) операция копирования с последующим изменением содержимого нескольких конкретных адресов для нового процесса, как при создании нового процесса посредством форка, считалась рискованной. Ошибки в текущем состоянии процесса могли быть скопированы в дочерний процесс. Здесь используется метафора порождения процесса: каждый компонент структуры памяти нового процесса создается заново с нуля. Метафора "спаун" (spawn) была позже принята в операционных системах Microsoft (1993). Компонент совместимости с POSIX в VM/CMS (OpenExtensions) предоставляет очень ограниченную реализацию форка, в которой родительский процесс приостанавливается на время выполнения дочернего, а дочерний и родительский процессы используют одно и то же адресное пространство. По сути, это vfork, обозначенный как fork. (Это применимо только к гостевой операционной системе CMS; другие гостевые операционные системы VM, такие как Linux, предоставляют стандартную функциональность fork.)