Документация по LinuxLinuxDoc.Ru 🔍

vfork - создает дочерний процесс и блокирует родительский

НАЗВАНИЕ
vfork - создает дочерний процесс и блокирует родительский

СИНТАКСИС
#include
#include

pid_t vfork(void);

СТАНДАРТНОЕ ОПИСАНИЕ

(Из черновика XPG4 / SUSv2 / POSIX) Функция vfork()
аналогична fork() за тем исключением, что поведение
процесса, созданного vfork(), неопределено, если он
модифицирует любые данные, кроме переменной типа pid_t,
используемой в качестве значения, возвращаемого vfork(),
или возвращается из функции, в которой была вызвана
функция vfork(), или вызывает любую функцию до удачного
исполнения _exit() или одной из функций семейства exec.

КОДЫ ОШИБОК
EAGAIN В системе слишком много процессов - попробуйте еще
раз.

ENOMEM Не хватает памяти для создания нового процесса.

ОПИСАНИЕ LINUX
vfork, так же, как и fork(2), создает дочерний процесс для
вызывающего. Подробности, возвращаемые значения и ошибки
смотрите в fork(2).

vfork() - это специальный вариант clone(2). Он
используется для создания новых процессов без копирования
таблиц страниц родительского процесса. Это может
использоваться в приложениях, критичных к
производительности, для создания дочерних процессов, сразу
же запускающих execve().

vfork() отличается от fork тем, что родительский процесс
блокируется до тех пор, пока дочерний процесс не вызовет
execve(2) или _exit(2). Дочерний процесс разделяет всю
память с родительским, включая стек, до тех пор, пока не
вызовет execve(). Дочерний процесс не должен выходить из
текущей функции или вызывать exit(), но может вызвать
_exit().

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

ИСТОРИЧЕСКАЯ СПРАВКА
В Linux функция fork() реализована при помощи страниц
"копирования при записи" (copy-on-write), поэтому
единственная задержка, возникающая при вызове fork(), -
это время, необходимое для создания копии таблиц страниц
родительского процесса и структуры задания дочернего
процесса. Однако, в прошлом fork() мог требовать создания
полной копии пространства данных вызывающего процесса, что
обычно не требовалось, так как сразу за fork() следовало
exec(). Поэтому для большей эффективности BSD предложило
системный вызов vfork, который не копировал адресное
пространство процесса, а использовал то же самое
пространство, блокируя родительский процесс до вызова
execve() или до прекращения своей работы. Использование
vfork было похоже на трюк: например, сохранность данных
родительсокго процесса зависела от того, какие переменные
содержатся в регистрах.

НАЙДЕННЫЕ ОШИБКИ
Скажем прямо, не очень хорошо, что в Linux существует
столь тяжелый пережиток прошлого. В man-странице BSD
написано следующее: "Этот системный вызов будет устранен
после того, как будут реализованы соответствующие
механизмы разделения ресурсов системы. Пользователи не
должны опираться на существующую семантику разделения
памяти vfork, то есть программа должна быть аналогична
программе с fork." Говоря проще, стандартное описание не
позволяет использовать vfork(), потому что, если
последующий за ним exec может не исполниться, что
произойдет дальше - не определено. Обработка сигналов еще
более сложна и различается от системы к системе. В
man-странице BSD написано следующее: "Для исключения
возможности остановки системы процессы, являющиеся
дочерними после исполнения vfork, никогда не получают
сигналов SIGTTOU или SIGTTIN; вместо этого вывод или ioctl
всегда разрешены, а попытки ввода приводят к ситуации
"EOF". На текущий момент (Linux 2.3.25) strace(1) не
может следовать за vfork() и требует изменений в коде
ядра.

ПРЕДЫСТОРИЯ
Системный вызов vfork() впервые появился в 3.0BSD. В BSD
4.4 он стал синонимом fork(), но NetBSD ввела его снова:
http://www.netbsd.org/Documentation/kernel/vfork.html . В
Linux этот системный вызов был эквивалентом fork()
примерно до ядра 2.2.0-pre6. Начиная с 2.2.0-pre9 (на i386
и немного позже на других архитектурах), он стал
независимым системным вызовом. Его поддержка быда
добавлена в glibc 2.0.112.

СООТВЕТСТВИЕ СТАНДАРТАМ
Системный вызов vfork может быть похожим на системные
вызовы с тем же именем в других ОС. Требования,
предъявляемые стандартами к vfork не такие жесткие, как
те, которые предъявляются к fork, поэтому будет достаточно
тех реализаций, в которых эти два вызова являются
синонимами. В частности, программист не может полагаться
на действия родительского процесса до вызова execve() или
_exit() и не может полагаться на специфичесоке поведение
т.н. "возникшей разделяемой памяти".
Читать новости Linux в Telegram
Linux - vfork - создает дочерний процесс и блокирует родительский
Мы в соцсетях ✉