Вилка – exec - Fork–exec

Вилка – exec это широко используемый метод в Unix посредством чего исполняющий процесс порождает новую программу.

Описание

вилка() это имя системный вызов что родительский процесс используется для «разделения» («вилки») на два идентичных процесса. После звонка вилка(), созданный дочерний процесс является точной копией родителя, за исключением возвращаемого значения вызова fork (). Это включает в себя открытые файлы, состояние регистров и все распределения памяти, включая исполняемый код программы. В некоторых случаях оба продолжают выполнять один и тот же двоичный файл, но часто один (обычно дочерний) переключается на запуск другого двоичного исполняемого файла с помощью exec () системный вызов.

Когда процесс разветвляется, полная копия исполняемой программы превращается в новый процесс. Этот новый процесс является дочерним по отношению к родительскому процессу и имеет новый идентификатор процесса (PID). В вилка() функция возвращает PID дочернего процесса родительскому процессу. В вилка() функция возвращает 0 дочернему процессу. Это позволяет двум идентичным процессам различать друг друга.

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

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

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

  пустота уборка(int сигнал) {    пока (waitpid((pid_t) (-1), 0, WNOHANG) > 0) {}  }

Когда дочерний процесс вызывает exec (), все данные в исходной программе теряются и заменяются работающей копией новой программы. Это известно как наложение. Хотя все данные заменены, файловые дескрипторы которые были открыты в родительском элементе, закрываются только в том случае, если программа явно их пометила близкий к руководителю. Это позволяет родителям, как правило, создавать трубка до звонка вилка() и использовать его для связи с исполняемой программой.

Майкрософт Виндоус не поддерживает модель fork-exec, так как не имеет системного вызова, аналогичного вилка(). В порождать() семейство функций, объявленных в process.h может заменить его в тех случаях, когда вызов вилка() непосредственно следует exec ().

Когда выполняется системный вызов fork WSL, lxss.sys выполняет некоторую начальную работу по подготовке к копированию процесса. Затем он вызывает внутренние NT API для создания процесса с правильной семантикой и создания потока в процессе с идентичным контекстом регистров. Наконец, он выполняет некоторую дополнительную работу для завершения копирования процесса и возобновляет новый процесс, чтобы он мог начать выполнение.

— Джек Хэммонс из Microsoft[1]

Рекомендации

  • "Файловые дескрипторы в fork (2) / exec (2)", Операционные системы (курс 304-427B), Франко Каллари, Департамент электротехники, Университет Макгилла
  • "вилка и выполнение", Тим Лав, Кембриджский университет Технический отдел
  • Расширенное программирование в среде UNIX, В. Ричард Стивенс, Эддисон-Уэсли ISBN  0-201-56317-7
  • Unix Power Tools, Джерри Пик, Тим О'Рейли Майк Лукидес, О'Рейли, ISBN  1-56592-260-3