.\" -*- coding: UTF-8 -*- .\" Copyright (c) 1999 Andries Brouwer (aeb@cwi.nl), 1 Nov 1999 .\" and Copyright 2006, 2012, 2017 Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\" 1999-11-10: Merged text taken from the page contributed by .\" Reed H. Petty (rhp@draper.net) .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH vfork 2 "2 мая 2024 г." "Справочные страницы Linux 6.9.1" .SH ИМЯ vfork \- создаёт дочерний процесс и блокирует родительский .SH БИБЛИОТЕКА Стандартная библиотека языка C (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf \fB#include \fP .P \fBpid_t vfork(void);\fP .fi .P .RS -4 Требования макроса тестирования свойств для glibc (см. \fBfeature_test_macros\fP(7)): .RE .P \fBvfork\fP(): .nf .\" || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED Since glibc 2.12: (_XOPEN_SOURCE >= 500) && ! (_POSIX_C_SOURCE >= 200809L) || /* Since glibc 2.19: */ _DEFAULT_SOURCE || /* glibc <= 2.19: */ _BSD_SOURCE Before glibc 2.12: _BSD_SOURCE || _XOPEN_SOURCE >= 500 .fi .SH ОПИСАНИЕ .SS "Описание в стандарте" (Из POSIX) Функция \fBvfork\fP() аналогична \fBfork\fP(2) за тем исключением, что поведение не определено, если процесс, созданный \fBvfork\fP(), изменяет любые данные, кроме переменной типа \fIpid_t\fP, используемой в качестве значения, возвращаемого \fBvfork\fP(), или возвращается из функции, из которой была вызвана функция \fBvfork\fP(), или вызывает любую функцию до удачного исполнения \fB_exit\fP(2) или одной из функций семейства \fBexec\fP(3). .SS "Описание в Linux" \fBvfork\fP(), так же как и \fBfork\fP(2), создаёт дочерний процесс для вызывающего процесса. Подробности, возвращаемые значения и ошибки смотрите в \fBfork\fP(2). .P \fBvfork\fP() \(em это специальный вариант \fBclone\fP(2). Он используется для создания новых процессов без копирования таблиц страниц родительского процесса. Это может использоваться в приложениях, критичных к производительности, для создания дочерних процессов, сразу же запускающих \fBexecve\fP(2). .P Вызов \fBvfork\fP() отличается от \fBfork\fP(2) тем, что вызывающая нить блокируется до тех пор, пока не завершится потомок (обычно, вызовом \fB_exit\fP(2) или, что ненормально, из\-за принятого необработанного сигнала) или не выполнит \fBexecve\fP(2). До этих пор потомок имеет общую память с родителем, включая стек. Потомок не должен выходить из текущей функции или вызывать \fBexit\fP(3) (что приводит к вызовы обработчиков выхода, настроенных родительским процессом и сбрасывает буферы \fBstdio\fP(3) родителя), но может вызвать \fB_exit\fP(2). .P Как и у \fBfork\fP(2), дочерний процесс, созданный \fBvfork\fP(), наследует копии различных атрибутов вызвавшего процесса (например, дескрипторы файлов, обработчики сигналов и текущий рабочий каталог); вызов \fBvfork\fP() отличается только в применении виртуального адресного пространства (как описывалось выше). .P Сигналы передаются родителю после того, как потомок разблокирует его память (т.е. после того, как потомок завершится или вызовет \fBexecve\fP(2)). .SS "Историческое описание" В Linux вызов \fBfork\fP(2) реализован при помощи страниц, «копируемых при записи» (copy\-on\-write), поэтому единственная задержка, возникающая при вызове \fBfork\fP(2) \(em это время, необходимое для создания копии таблиц страниц родительского процесса и уникальной структуры описания задачи дочернего процесса. Однако, в прошлом для \fBfork\fP(2) могло требоваться создание полной копии пространства данных вызывающего процесса, что часто было ненужно, так как в потомке сразу следовал запуск функции \fBexec\fP(3). Поэтому для большей эффективности в BSD был предложен системный вызов \fBvfork\fP(), который не копировал адресное пространство процесса, а использовал то же самое пространство и управления нитью, блокируя родительский процесс до вызова \fBexecve\fP(2) или до прекращения работы потомка. Родительский процесс останавливался до тех пор, пока потомок использовал его ресурсы. Использование \fBvfork\fP() было ненадёжно: например, сохранность данных родительского процесса зависела от того, хранились ли на тот момент переменные в регистрах. .SH ВЕРСИИ .\" In AIXv3.1 vfork is equivalent to fork. Требования, предъявляемые стандартами к \fBvfork\fP(), не такие жёсткие как те, которые предъявляются к \fBfork\fP(2), поэтому в реализации достаточно просто сделать их синонимами. В частности, программист не может полагаться на блокировку родителя до завершения потомка или до вызова им \fBexecve\fP(2), и не может полагаться на специфическое поведение возникновения общей памяти. .P Some consider the semantics of \fBvfork\fP() to be an architectural blemish, and the 4.2BSD man page stated: \[lq]This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of \fIvfork\fP as it will, in that case, be made synonymous to \fIfork\fP.\[rq] However, even though modern memory management hardware has decreased the performance difference between \fBfork\fP(2) and \fBvfork\fP(), there are various reasons why Linux and other systems have retained \fBvfork\fP(): .IP \[bu] 3 Для некоторых критичных к производительности приложений очень важна та маленькая прибавка к производительности, предоставляемая \fBvfork\fP(). .IP \[bu] .\" http://stackoverflow.com/questions/4259629/what-is-the-difference-between-fork-and-vfork .\" http://developers.sun.com/solaris/articles/subprocess/subprocess.html .\" http://mailman.uclinux.org/pipermail/uclinux-dev/2009-April/000684.html .\" \fBvfork\fP() can be implemented on systems that lack a memory\-management unit (MMU), but \fBfork\fP(2) can't be implemented on such systems. (POSIX.1\-2008 removed \fBvfork\fP() from the standard; the POSIX rationale for the \fBposix_spawn\fP(3) function notes that that function, which provides functionality equivalent to \fBfork\fP(2)+ \fBexec\fP(3), is designed to be implementable on systems that lack an MMU.) .IP \[bu] В системах с малым количеством памяти \fBvfork\fP() при запуске новой программы не выполняет временное выделение памяти (смотрите описание \fI/proc/sys/vm/overcommit_memory\fP в \fBproc\fP(5)) (это особенно полезно, если огромный родительский процесс хочет выполнить маленькую вспомогательную программу в дочернем процессе). Вызов \fBfork\fP(2) в этом случае или потребуется выделения количества памяти как у родительского процесса (если включён жёсткий учёт обязательств) или перерасходует память с риском завершения процесса посредством сторожа расходования памяти ядра (OOM). .SS "Замечания, касающиеся Linux" Обработчики fork, установленные с помощью \fBpthread_atfork\fP(3), не вызываются когда многонитиевая программа использует вызовы библиотеки нитей NPTL \fBvfork\fP(). Обработчики fork вызываются в этом случае в программе, в которой используется библиотека нитей LinuxThreads. (См. в \fBpthreads\fP(7) описание библиотек нитей Linux.) .P Вызов \fBvfork\fP() эквивалентен вызову \fBclone\fP(2) со следующим значением \fIflags\fP: .P .in +4n .EX CLONE_VM | CLONE_VFORK | SIGCHLD .EE .in .SH СТАНДАРТЫ None. .SH ИСТОРИЯ 4.3BSD; POSIX.1\-2001 (помечен как УСТАРЕВШИЙ). Из POSIX.1\-2008 описание \fBvfork\fP() было удалено. .P .\" In the release notes for 4.2BSD Sam Leffler wrote: `vfork: Is still .\" present, but definitely on its way out'. .\" The \fBvfork\fP() system call appeared in 3.0BSD. In 4.4BSD it was made synonymous to \fBfork\fP(2) but NetBSD introduced it again; see .UR http://www.netbsd.org\:/Documentation\:/kernel\:/vfork.html .UE . In Linux, it has been equivalent to \fBfork\fP(2) until Linux 2.2.0\-pre6 or so. Since Linux 2.2.0\-pre9 (on i386, somewhat later on other architectures) it is an independent system call. Support was added in glibc 2.0.112. .SH CAVEATS Потомок не должен изменять память не ожидаемым образом, так как такие изменения будут видны родительскому процессу после завершения потомка или выполнении другой программы. При таком отношении особенно остро стоит проблема в обработчиках сигналов: если обработчик сигналов, вызванный в потомке (созданном \fBvfork\fP()), изменяет память, то эти изменения могут привести к нарушению целостности состояния процесса с точки зрения родителя (например, изменения памяти были бы видны родителю, а изменения состояния открытых файловых дескрипторов не видны). .P .\" Если \fBvfork\fP() вызывается многонитиевом процессе, то в ожидании завершения процесса или запуска новой программы приостанавливается только вызывающая нить. Это означает, что потомок совместно использует адресное пространство другим выполняющимся кодом. Это может быть опасно, если другая нить в родительском процессе изменяет полномочия (с помощью \fBsetuid\fP(2) и подобных), так как теперь есть два процесса с разным уровнем прав, выполняемых в одном адресном пространстве. Как пример представим, что многонитиевая программа, работающая с правами суперпользователя, создаёт потомка с помощью \fBvfork\fP(). После \fBvfork\fP() нить в родительском процессе понижает права процесса до непривилегированных, чтобы выполнить некий недоверенный код (например, модуль, открытый через \fBdlopen\fP(3)). В этом случае появляется уязвимость, если родительский процесс использует \fBmmap\fP(2) для отображения кода, то он будет выполнен в привилегированном дочернем процессе. .SH ОШИБКИ .\" .\" As far as I can tell, the following is not true in Linux 2.6.19: .\" Currently (Linux 2.3.25), .\" .BR strace (1) .\" cannot follow .\" .BR vfork () .\" and requires a kernel patch. Обработка сигналов ещё более запутана и различается от системы к системе. В справочной странице BSD написано следующее: «Для исключения возможности взаимных блокировок процессы, находящиеся в середине исполнения \fBvfork\fP(), никогда не получат сигналов \fBSIGTTOU\fP или \fBSIGTTIN\fP, хотя вывод или \fIioctl\fP всегда разрешены, а попытки ввода приводят к ситуации появления конца файла». .SH "СМОТРИТЕ ТАКЖЕ" \fBclone\fP(2), \fBexecve\fP(2), \fB_exit\fP(2), \fBfork\fP(2), \fBunshare\fP(2), \fBwait\fP(2) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства разработал(и) Azamat Hackimov , Dmitriy Ovchinnikov , Dmitry Bolkhovskikh , Katrin Kutepova , Yuri Kozlov и Иван Павлов . .PP Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, .UR https://www.gnu.org/licenses/gpl-3.0.html .UE версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ. .PP Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу .MT списка рассылки русских переводчиков .ME .