Provided by: manpages-ru_0.98-4_all bug

ИМЯ

       clone - создать процесс-потомок

ОБЗОР

       #include <sched.h>

       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) или после получения
       фатального сигнала.

       Аргумент   child_stack   задаёт    положение    стека,    используемого
       процессом-потомком.    Начиная   с  момента,  когда  процесс-потомок  и
       вызывающий процесс могут разделять  память,  процесс-потомок  не  может
       выполняться  в  том  же  стеке,  что  и  вызывающий процесс. Вызывающий
       процесс должен, таким образом, установить пространство памяти для стека
       процесса-потомка  и  передать  указатель  на  это пространство в вызове
       clone.  Стеки растут вниз для всех  процессоров,  на  которых  работает
       Linux  (за  исключением  HP PA процессоров), так что child_stack обычно
       указывает на наиболее высокий  адрес  в  пространстве  памяти,  которое
       устанавливается для стека процесса-потомка.

       Младший байт flags содержит номер сигнала, который посылается родителю,
       когда потомок умирает. Если этот сигнала задаётся как нечто отличное от
       SIGCHLD,  то  родительский  процесс  должен  задать  опцию  __WALL  или
       __WCLONE при  ожидании  завершения  работы  потомка  с  помощью  вызова
       wait(2).   Если  никакой  сигнал  не  задан, то родительский процесс не
       извещается сигналом, когда потомок завершается.

       Аргумент flags состоит из одного или более данных ниже битовых  флагов,
       которые  складываются  по правилам битового сложения (OR). Флаги задают
       порядок процессов и то, что разделяется между  вызывающим  процессом  и
       процессом-потомком:

       CLONE_PARENT
              (ветка  Linux  2.4 и выше) Если установлен флаг CLONE_PARENT, то
              родитель нового потомка (как возращает вызов  getppid(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_NEWNS
              (Начиная  с Linux 2.4.19) Запускает потомок в новом пространстве
              имён.

              Каждый   процесс   живёт   в   некотором   пространстве    имён.
                  процесса - это данные (список смонтированных
              файловых систем), описывающие файловую  иерархию,  видимую  этим
              процессом.  После  вызова fork(2) или clone(2) где не установлен
              флаг CLONE_NEWNS, потомок живёт в том же пространстве имён,  что
              и  родитель.   Системные  вызовы  mount(2)  и umount(2) изменяют
              пространство имён  вызывающего  процесса  и,  с  этого  момента,
              оказывают  эффект  на  все  процессы,  которые  живут  в этом же
              пространстве имён, но не оказывают эффект на процессы  в  других
              пространствах имён.

              После  вызова  clone(2) где флаг CLONE_NEWNS установлен, потомок
              запускается в новом пространстве имён, инициализированном копией
              пространства имён родителя.

              Только   привелегированный   процесс  может  устанавливать  флаг
              CLONE_NEWNS.  Не  допускается  совместное  использование  флагов
              CLONE_NEWNS и CLONE_FS в одном вызове 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   установлен,   вызывающий   процесс   и
              процесс-потомок запускаются в  том  же  пространстве  памяти.  В
              частности, записи в память, выполненные вызывающим процессом или
              процессом-потомком также видны из другого процесса.  Кроме того,
              любые  отражения  памяти (mapping) или их завершение (unmapping)
              выполняемые через mmap(2) или munmap(2) потомком или  вызывающим
              процессом, также оказывают эффект на другой процесс.

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

       CLONE_PID
              Если  флаг  CLONE_PID  установлен,  процесс-потомок  создаётся с
              таким же идентификатором процесса (ID) как и вызывающий процесс.

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

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

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

              Если  флаг  CLONE_THREAD  не устанлвен, то потомок размещается в
              своей собственной (новой) группе тредов, где ID группы такой  же
              как и идентификатор процесса.

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

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

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

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

       В случае успеха, в вызывающий тред возращается PID процесса-потомка.  В
       случае  ошибки, в контекст вызываюего процесса возвращается -1, процесс
       потомок   не   будет   создан   и   значение   errno    устанавливается
       соответствующим образом.

ОШИБКИ

       EAGAIN Уже запущено слишком много процессов.

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

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

       EINVAL Оба флага CLONE_FS и CLONE_NEWNS были заданы в аргументе  flags.

       EINVAL CLONE_THREAD  был  задан, но CLONE_SIGHAND нет. (Начиная с Linux
              2.5.35.)

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

БАГИ

       В версии ядра 2.1.97, флаг CLONE_PID не должен использоваться, так  как
       другие   части  данного  ядра  и  большинство  системного  программного
       обеспечения  рассчитывают,  что   идентификаторы   процессов   являются
       уникальными.

       Вызов  clone  отсутствует в libc версии 5.  libc 6 (известная как glibc
       2)  предоставляет  вызов  clone  как  описывается  на  данной  странице
       руководства.

ЗАМЕЧАНИЯ

       Для  ядер  версий  2.4.7-2.4.18  флаг CLONE_THREAD неявно подразумевает
       флаг CLONE_PARENT.

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

       Вызовы clone и sys_clone являются специфичными для Linux  и  не  должны
       использоваться в программах, которые задуманы как переносимые на другие
       платформы.  Для   программирования   приложений,   использующих   треды
       (несколько  тредов  управления  в  одной и той же области памяти) лучше
       использовать библиотечную реализацию POSIX 1003.1c  thread  API,  такую
       как    библиотека    LinuxThreads    (включённая    в   glibc2).    См.
       pthread_create(3).

       Данная страница руководства соответствует ядрам  2.0.x,  2.1.x,  2.2.x,
       2.4.x, а также glibc 2.0.x и 2.1.x.

СМОТРИ ТАКЖЕ

       fork(2), wait(2), pthread_create(3)

ПЕРЕВОД

       Перевёл с английского Виктор Вислобоков <corochoone@perm.ru> 2004