Я понимаю разницу между fork, vfork, exec, execv, execp. Так что, пожалуйста, не разглагольствуйте об этом. Мой вопрос касается дизайна создания процесса unix. Почему дизайнеры подумали о создании двух отдельных вызовов ( fork и exec ) вместо того, чтобы оставить один плотный вызов ( spawn ). Был ли хороший дизайн API причиной того, что разработчики имели больше контроля над созданием процессов? Это из-за производительности, чтобы мы могли отложить выделение таблицы процессов и других структур ядра дочернему элементу до копирования при записи или копирования при доступе?
почему fork и exec хранятся 2 отдельных вызова
Ответы (5)
Основная причина, вероятно, заключается в том, что разделение шагов fork()
и exec()
позволяет выполнять произвольную настройку дочерней среды с помощью других системных вызовов. Например, вы можете:
- Настроить произвольный набор дескрипторов открытых файлов;
- Изменить маску сигнала;
- Установить текущий рабочий каталог;
- Установить группу процессов и/или сеанс;
- Установите пользователя, группу и дополнительные группы;
- Установите жесткие и мягкие ограничения ресурсов;
...и многое другое. Если бы вы объединили эти вызовы в один вызов spawn()
, у него должен был бы быть очень сложный интерфейс, чтобы иметь возможность кодировать все эти возможные изменения в дочерней среде — и если бы вы когда-нибудь добавили новую настройку, интерфейс нужно изменить. С другой стороны, отдельные шаги fork()
и exec()
позволяют вам использовать обычные системные вызовы (open()
, close()
, dup()
, fcntl()
, ...) для управления дочерней средой до exec()
. Новая функциональность (например, capset()
) легко поддерживается.
fork и exec делают совершенно разные вещи.
- fork() - дублирует процесс
- exec() - заменяет процесс
Есть много причин использовать одно без другого. Вы можете разветвить дочерние процессы, которые выполняют задачи от имени вашего управляющего родительского приложения, например, это довольно распространено в мире Unix. И вы можете, например. настройте предварительные условия для какого-то другого необычного приложения, а затем запустите его из своего приложения запуска, даже не используя fork.
exec
, перезапустите приложение (например, сетевые демоны делают это, если обнаруживают новую версию своего двоичного файла и простаивают).
- person Šimon Tóth; 23.02.2011
spawn
можно было бы реализовать эффективнее, чем fork + exec
? Мне кажется, что spawn
не нужно копировать сегмент данных, как это делает fork.
- person sasha.sochka; 10.02.2014
fork
ed процессов.
- person val is still with Monica; 04.07.2018
Насколько я знаю, изначально была только функция fork(). Но соображения производительности требуют создания функции exec(), которая не воссоздает структуры ядра, которые будут немедленно перезаписаны. ‹-- Это неправильно.
Возникает проблема с производительностью, когда процессу необходимо создать дочерний процесс, который не является копией самого себя. Функция fork() копирует данные ядра, связанные с процессом, которые будут немедленно заменены функцией exec(). Таким образом, был введен vfork(), который не копирует лишние данные ядра и любые данные процесса; после этого ожидается, что процесс вызовет что-то похожее на exec(), и родитель приостанавливается до тех пор, пока это не сделает дочерний процесс. См. раздел «Ошибки» для описания проблем с vfork().
exec
?
- person Philipp; 23.02.2011
Из черновика книги xv6 простая обучающая операционная система в стиле Unix. система, используемая в курсе MIT 6.828:
Теперь должно быть ясно, почему это хорошая идея, чтобы fork и exec были отдельными вызовами. Потому что, если они разделены, оболочка может разветвить дочерний элемент, использовать open, close, dup в дочернем элементе для изменения стандартных дескрипторов входных и выходных файлов, а затем выполнить exec. Никаких изменений в исполняемой программе (cat в нашем примере) не требуется. Если бы fork и exec были объединены в один системный вызов, то для перенаправления стандартного ввода и вывода оболочке потребовалась бы какая-то другая (вероятно, более сложная) схема, или самой программе пришлось бы понимать, как перенаправлять ввод-вывод.
В основном, как говорит caf ниже, но дает хорошую ссылку. Реализация простой оболочки, вероятно, прояснила бы причины.
fork() можно использовать только для создания дочернего процесса. Можно выполнить только репликацию родителя. В то время как exec() можно использовать для запуска любого нового процесса в системе. Я не вижу никакой корреляции выше двух.
fork
или exec
, а есть только их комбинация (на языке Unix за fork
сразу следует exec
).
- person Philipp; 23.02.2011
fork
, используяspawn
? - person Šimon Tóth   schedule 23.02.2011