Linux repositories inspector
Linux
2017-09-15

man-pages-ru

Russian man pages from the Linux Documentation Project

manpages-dev

Manual pages about using GNU/Linux for development

man-pages

Linux kernel and C library user-space interface documentation

ИМЯ

fork - создаёт дочерний процесс

ОБЗОР

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);

ОПИСАНИЕ

Вызов fork() создаёт новый процесс посредством копирования вызывающего процесса. Новый процесс считается дочерним процессом. Вызывающий процесс считается родительским процессом.
Дочерний и родительский процессы находятся в отдельных пространствах памяти. Сразу после fork() эти пространства имеют одинаковое содержимое. Запись в память, отображение файлов (mmap(2)) и снятие отображения (munmap(2)), выполненных в одном процессе, ничего не изменяет в другом.
Дочерний процесс является точной копией родительского процесса за исключением следующих моментов:
* Потомок имеет свой уникальный идентификатор процесса, и этот PID (идентификатор процесса) не совпадает ни с одним существующим идентификатором группы процессов (setpgid(2)) или сеансов.
* Идентификатор родительского процесса у потомка равен идентификатору родительского процесса.
* Потомок не наследует блокировки памяти родителя (mlock(2), mlockall(2)).
* Счётчики использования ресурсов (getrusage(2)) и времени ЦП у потомка сброшены в 0.
* Набор ожидающих сигналов потомка изначально пуст (sigpending(2)).
* Потомок не наследует значения семафоров родителя (semop(2)).
* Потомок не наследует связанные с процессом блокировки родителя (fcntl(2)) (с другой стороны, он наследует блокировки файловых описаний fcntl(2) и блокировки flock(2)).
* Потомок не наследует таймеры родителя (setitimer(2), alarm(2), timer_create(2)).
* Потомок не наследует ожидающие выполнения операции асинхронного ввода-вывода (aio_read(3), aio_write(3)) и контексты асинхронного ввода-вывода родителя (см. io_setup(2)).
Все перечисленные атрибуты указаны в POSIX.1. Родитель и потомок также отличаются по следующим атрибутам процесса, которые есть только в Linux:
* Потомок не наследует уведомления об изменении каталога (dnotify) родителя (смотрите описание F_NOTIFY в fcntl(2)).
* Настройка PR_SET_PDEATHSIG у prctl(2) сбрасывается, и поэтому потомок не принимает сигнал о завершении работы родителя.
* Резервное значение по умолчанию устанавливается равным родительскому текущему резервному значению таймера. Смотрите описание PR_SET_TIMERSLACK в prctl(2).
* Отображение памяти, помеченное с помощью флага MADV_DONTFORK через madvise(2), при fork() не наследуется.
* Память в диапазонах адресов, которые были помечены с помощью madvise(2) флагом MADV_WIPEONFORK, обнуляются в потомке после fork() (флаг MADV_WIPEONFORK остаётся в потомке у этих диапазонов адресов).
* Сигнал завершения работы потомка всегда SIGCHLD (см. clone(2)).
* Биты прав доступа к порту, установленные с помощью ioperm(2), не наследуются потомком; потомок должен установить все нужные ему биты с помощью ioperm(2).
Также стоит учитывать следующее:
* Процесс потомка создаётся с одиночной нитью — той, которая вызвала fork(). Всё виртуальное адресное пространство родителя копируется в потомок, включая состояние мьютексов, условных переменных и других объектов pthreads; в случае проблем с этим может помочь pthread_atfork(3).
* В многонитевой программе после fork() потомок может безопасно вызывать только безопасные-асинхронные-сигнальные функции (смотрите signal-safety(7)) до тех пор, пока не вызовет execve(2).
* Потомок наследует копии набора открытых файловых дескрипторов родителя. Каждый файловый дескриптор в потомке ссылается на то же описание файла что и родитель (смотрите open(2)). Это означает, что два файловых дескриптора совместно используют флаги состояния открытого файла, смещение файла и атрибуты ввода-вывода, управляемые сигналами (смотрите описание F_SETOWN и F_SETSIG в fcntl(2)).
* Потомок наследует копии набора файловых дескрипторов открытых очередей сообщений родителя (смотрите mq_overview(7)). Каждый файловый дескриптор в потомке ссылается на то же описание открытой очереди сообщений что и родитель. Это означает, что два файловых дескриптора совместно используют флаги (mq_flags).
* Потомок наследует копии набора потоков открытых каталогов родителя (смотрите opendir(3)). В POSIX.1 сказано, что соответствующие потоки каталогов в родителе и потомке могут совместно использовать позицию в потоке каталога; в Linux/glibc они не могут этого делать.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном завершении родителю возвращается PID процесса-потомка, а процессу-потомку возвращается 0. При ошибке родительскому процессу возвращается -1, процесс-потомок не создаётся, а значение errno устанавливается в соответствующее значение.

ОШИБКИ

EAGAIN
Возникло системного ограничение на количество нитей. Есть несколько ограничений, которые могут вызвать эту ошибку:
* RLIMIT_NPROC (задаётся с помощью setrlimit(2)), который ограничивает количество процессов и ните для реального ID пользователя;
* было достигнуто системное ограничение ядра на количество процессов и нитей, /proc/sys/kernel/threads-max (смотрите proc(5));
* достигнуто максимальное количество PID, /proc/sys/kernel/pid_max (смотрите proc(5)); или
* достигнуто ограничение на PID (pids.max), наложенное контроллером cgroup на «номер процесса» (PID).
EAGAIN
Вызывающий работает по алгоритму планирования SCHED_DEADLINE и у него не установлен флаг сброса-при-fork (reset-on-fork). Смотрите sched(7).
ENOMEM
Вызов fork() завершился с ошибкой из-за невозможности разместить необходимые структуры ядра, потому что слишком мало памяти.
ENOMEM
Была попытка создания дочерний процесс в пространстве имён PID, чей процесс «init» завершил работу. Смотрите pid_namespaces(7).
ENOSYS
Вызов fork() не поддерживается на этой платформе (например, из-за того, что аппаратное обеспечение не содержит блока управления памятью (MMU)).
ERESTARTNOINTR (начиная с Linux 2.6.17)
Системный вызов был прерван сигналом и перезапущен (может быть замечено только при трассировке).

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

ЗАМЕЧАНИЯ

В Linux, fork() реализован с помощью «копирования страниц при записи» (copy-on-write, COW), поэтому расходы на вызов состоят из времени и памяти, требуемой на копирование страничных таблиц родителя и создания уникальной структуры, описывающей задачу.

Отличия между библиотекой C и ядром

Начиная с версии 2.3.3, вместо того, чтобы вызывать системный вызов fork(), обёрточная функция fork() в glibc, как часть реализации нитей NPTL, вызывает clone(2) с флагами, которые обеспечивают поведение традиционного системного вызова (вызов fork() эквивалентен вызову clone(2), если значение равно flags SIGCHLD). Обёртка в glibc вызывает все обработчики при ветвлении (fork), которые были зарегистрированы с помощью pthread_atfork(3).

ПРИМЕР

Смотрите pipe(2) и wait(2).

REFERENCED BY

xargs(1), authbind(1), fork(3am), sotruss(1), ibv_fork_init(3), _exit(2), alarm(2), bpf(2), chdir(2), chroot(2), clone(2), eventfd(2), execve(2), fcntl(2), flock(2), getitimer(2), getpid(2), getpriority(2), getrlimit(2), gettid(2), ioctl_userfaultfd(2), ioperm(2), iopl(2), kcmp(2), keyctl(2), lseek(2), madvise(2), memfd_create(2), mlock(2), mmap(2), mount(2), nice(2), open(2), perf_event_open(2), pipe(2), prctl(2), ptrace(2), sched_setaffinity(2), sched_setattr(2), sched_setscheduler(2), seccomp(2), select_tut(2), semop(2), set_mempolicy(2), setns(2), setpgid(2), setsid(2), shmop(2), sigaction(2), sigaltstack(2), signalfd(2), sigpending(2), sigprocmask(2), timer_create(2), timerfd_create(2), umask(2), unshare(2), userfaultfd(2), vfork(2), wait(2), wait4(2), atexit(3), daemon(3), exec(3), on_exit(3), openpty(3), popen(3), posix_spawn(3), sem_init(3), system(3), core(5), proc(5), capabilities(7), cgroups(7), cpuset(7), credentials(7), environ(7), epoll(7), mq_overview(7), pid_namespaces(7), pipe(7), pthreads(7), sched(7), signal-safety(7), signal(7), user_namespaces(7), strace(1), setsid(1), rc(1plan9), cr_restart(1), downtimed(8), hylafax-log(5), faxq(8), iv_signal(3), pthread_atfork(3), sysklogd(8), dbpmda(1), pmcd(1), __pmProcessAddArg(3), __pmProcessClosePipe(3), pseudo(1), sec(1), slrnface(1), search++(1), msocket(2viewos), sigstack(3), vlimit(3), fork(2), mount(8), persistent-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user-session-keyring(7), hylafax-log(5f), faxq(8c), halockrun(1), bosh(1), obosh(1), rt_sigsuspend(2), proc(3ast), spawnveg(3ast), pidfd_open(2), trafgen(8)
⇧ Top