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

clone - функция, создающая дочерний процесс

НАЗВАНИЕ
clone - функция, создающая дочерний процесс

СИНТАКСИС
#include

int clone(int (*fn)(void *), void *child_stack, int flags,
void *arg);

_syscall2(int, clone, int, flags, void *, child_stack);

ОПИСАНИЕ
clone создает новый процесс аналогично fork(2). clone
является библиотечной функцией для системного вызова
clone, переправляющего на sys_clone. Описание sys_clone
приведено далее по тексту. В отличие от fork(2), эти
вызовы позволяют дочернему процессу разделять такие части
его исполняемого содержания с вызывающими процессами, как
память, таблица описателей файлов, таблица обработчиков
сигналов. (Заметим, что в данном руководстве "вызывающий
процесс" обычно соотвествует "родительскому процессу". Но
обязательно посмотрите описание CLONE_PARENT далее по
тексту.) Основное использование clone - это создание
множества подпроцессов программы, которые работают в общем
пространстве памяти. Когда дочерний процесс создан clone,
он запускает функцию приложения fn(arg). (Это отличается
от поведения fork(2), где исполнение продолжается в
дочернем процессе с точки разделения вызова fork(2).
Аргумент fn указывает на функцию, вызываемую дочерним
процессом в начале работы. Аргумент arg передается
функции fn. Когда функция fn(arg) выполнена, дочерний
процесс закрывается. Целое число, возвращаемое fn,
является для дочерней программы кодом выхода. Дочерний
процесс можно закрыть при помощи exit(2); также он может
закрыться при получении сигнала о прерывании работы (fatal
signal). Аргумент child_stack указывает на
местонахождение стека, использованного дочерним процессом.
Хотя дочерний и родительский процессы могут разделять
память, дочернему процессу нельзя ипспользовать тот-же
стек для исполнения, что и вызывающему процессу. Поэтому
родительский процесс должен выделить пространство в памяти
под стек дочернего процесса и передать указатель на это
пространство функции clone. На всех процессорах с
реализацией Linux (кроме процессоров HP PA) стек "растет
вниз". child_stack обычно указывает на самый последний
адрес памяти для стека дочернего процесса. Последний байт
из flags содержит номер сигнала, который посылается
родительскому процессу при закрытии дочернего. Если этот
сигнал отличается от SIGCHLD, то родительский процесс
должен указать опции __WALL или __WCLONE для ожидания
дочернего процесса через wait(2). Если не указан сигнал,
то родительскому процессу не сообщается о завершении
дочернего процесса. Значение flags может быть логически
сложено побитно, с одной или несколькими константами, для
определения того, что является общим между вызывающим и
дочерним процессами:

CLONE_PARENT
(Linux 2.4 и далее) Если CLONE_PARENT установлен,
то родитель нового процесса (возвращаемый от getp-
pid(2)) будет такой же, как и у вызывающего
процесса. Если значение CLONE_PARENT не
установлено, то (аналогично fork(2)) родитель
процесса есть вызывающий процесс.

Заметим, что имменно родительский процесс, как
возвращается от getppid(2), выдает сигнал при
завершении работы дочернего процесса, поэтому если
CLONE_PARENT установлен, то сигнализировать будет
родитель вызывающего процесса, а не сам вызывающий
процесс.

CLONE_FS
Если значение CLONE_FS указано, то вызывающий и
дочерний процессы используют общую информацию
файловой системы. Это касается как корневого
каталога, так и рабочего и umask. Любой вызов:
chroot(2), chdir(2) или umask(2), производится
вызывающим или дочерним процессами и отражается с
одного на другой. Если значение CLONE_FS не
указано, то дочерний процесс работает с копией
информации файловой системы вызывающего процесса,
сделанной сразу после вызова clone. Вызовы
chroot(2), chdir(2), umask(2), сделанные после
этого другими процессами, не влияют на остальные
процессы.

CLONE_FILES
Если значение CLONE_FILES указано, то вызывающий и
дочерний процессы используют один файл с таблицей
описателей. Описатели файлов ссылаются на файлы,
используемые как вызывающим, так и дочерним
процессом. Любой описатель файла, созданный одним
из процессов, доступен другому процессу. Если один
из процессов закрывает описатель файла или меняет
его флаги, то это отражается на другом процессе.
Если значение CLONE_FILES не указано, то дочерний
процесс получает копию всех описателей файла,
открытых в вызывающем процессе во время __clone.
Операции, производимые далее над описателями либо
вызывающим, либо дочерним процессом, не влияют на
другие процессы.

CLONE_SIGHAND
Если значение CLONE_SIGHAND указано, то вызывающий
и дочерний процессы используют общую таблицу
обработчиков сигнала. Если один из процессов
вызывает sigaction(2), чтобы сменить свою реакцию
на сигнал, то реакция изменится и у второго. Так
или иначе, родительский и дочерний процессы имеют
различные маски сигналов и набор ожидаемых
сигналов. Один из процессов при задании команды
sigprocmask(2) может заблокировать или
разблокировать сигналы для себя (это не отразится
на другом процессе). Если CLONE_SIGHAND не
указано, то дочерний процесс получает копию таблицы
обработчиков сигнала от вызвавшего процесса при
вызове clone . После этого вызов sigaction(2),
сделанный одним из процессов, не будет влиять на
другой.

CLONE_PTRACE
Если CLONE_PTRACE указано, и отслеживается
вызывающий процесс, то отслеживаться будет также и
дочерний процесс (см. ptrace(2)).


CLONE_VFORK
Если CLONE_VFORK установлен, то выполнение
вызывающего процесса задерживается, пока дочерний
процесс не раздаст свои виртуальные ресурсы памяти
через вызов execve(2) или _exit(2) (аналогично
vfork(2)).

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


CLONE_VM
Если значение CLONE_VM установлено, то вызывающий и
дочерний процессы работают в одном пространстве
памяти. В частности, записи, сделанные в памяти
вызывающим или дочерним процессом, видны из других
процессов. Более того, если родительский или
дочерний процессы отражают информацию (или снимают
ее отражение) с помощью функций mmap(2) или mun-
map(2), то отраженная информация будет влиять на
все остальные процессы.

Если CLONE_VM не установлено, то дочерний процесс
запускается в отдельной копии пространства памяти
вызывающего процесса во время clone. Записи в
память или отражение/снятие отражения выполняемые
одним из процессов не влияет на другие, аналогично
fork(2).


CLONE_PID
Если значение CLONE_PID указано, то дочерний
процесс создан с тем же уникальным идентификатором
процесса (PID), что и вызывающий процесс. Если
значение CLONE_PID не указано, то дочерний процесс
будет обладать уникальным идентификатором процесса
(PID), отличным от вызвавшего его процесса.

Этот флаг может быть указан только системным
процессом загрузки (PID 0).


CLONE_THREAD
(Linux 2.4 и далее) Если CLONE_THREAD установлено,
то дочерний процесс помещается в ту же группу
задач, что и вызывающий процесс.

Если CLONE_THREAD не установлено, то дочерний
процесс помещается в его собственную группу задач,
чей идентификатор равен идентификатору процесса.

(Группы задач /- это особенность, добавленная в
Linux 2.4 для поддержки понятия задач POSIX, как
набора задач, имеющих одинаковый идентификатор
процесса. В Linux 2.4, вызовы getpid(2) возвращают
идентификатор группы задач вызывающего процесса.)

Системный вызов sys_clone больше соответствует fork(2) в
том, что выполнение в дочернем процессе продолжается с
точки вызова. Поэтому sys_clone требует наличия только
аргументов flags и child_stack, имеющих аналогичные
значения и для clone. (Заметим, что порядок этих
аргументов отличается от clone.)

Другое отличие sys_clone заключается в том, что аргументом
child_stack может быть ноль, в этом случае семантика
копирования-при-записи проверяет, что дочерний процесс
получает отдельные копии страниц стека, если процесс
изменяет стек. В этом случае для корректной работы
параметр CLONE_VM не должен указываться.


ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При удачном завершении работы вызывающему процессу
возвращается PID дочернего процесса. При ошибке вместо
PID вызывающему процессу возвращается -1, дочерний процесс
не создается, а переменной errno присваивается
соответствующее значение.

КОДЫ ОШИБОК
EAGAIN Запущено слишком много процессов.

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

EINVAL Возвращается от clone при нулевых значениях,
указанных для child_stack.

EPERM CLONE_PID было указано процессом с ненулевым
идентификатором процесса.

НАЙДЕННЫЕ ОШИБКИ

Как и в версии ядра 2.1.97, флаг CLONE_PID не должен быть
использован, так как другие части ядра и системы
рассматривают PID как уникальный. Нет функции clone в
libc версии 5. В libc версии 6 (как и в glibc 2) clone
работает так, как описано в этой инструкции.

СООТВЕТСТВИЕ СТАНДАРТАМ
Вызовы clone и sys_clone являются специфичными только для
Linux, поэтому их не рекомендуется использовать в
программах, предназначенных для последующего портирования.
Для программирования многозадачных приложений (работающих
в одном адресном пространстве) лучше всего использовать
библиотеки, имеющие API стандарта POSIX 1003.1c, такие,
как LinuxThreads library (включенную в glibc2).
Просмотрите pthread_create(3). Это руководство
соответствует ядрам 2.0.x, 2.1.x, 2.2.x, 2.4.x и glibc
2.0.x и 2.1.x.
Читать новости Linux в Telegram
Linux - clone - функция, создающая дочерний процесс
Мы в соцсетях ✉