Unix-system-calls-clone2

提供:Dev Guides
移動先:案内検索

[top]#

|http://www.google.com/[Google] | a|

Web This Site
  • 初心者向けのUnix *
  • 高度なUnix *

選択した読書

Copyright©2014 by finddevguides

[cols=",,,,,,,",]

| |  Home   | |  References   | |  Discussion Forums   | |  About TP  

[width="100%",cols="100%",]

a| == clone()-Unix、Linuxシステムコール

[[File:]] image :http://www.finddevguides.com/images/next.gif [next] image:http://www.finddevguides.com/add- this.gif [AddThisソーシャルブックマークボタン]

広告

NAME

clone、__ clone2-子プロセスを作成します

概要

#include <sched.h> int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... /*pid_t* pid, struct user_desc *tls ", pid_t *" ctid " */);" int __clone2(int (*fn)(void *), void *child_stack_base, size_t stack_size, int flags, void *arg, ... /*pid_t* pid, struct user_desc *tls ", pid_t *" ctid " */);"

説明

*clone* ()は、 *fork* (2)と同様の方法で、新しいプロセスを作成します。 これは、実際には基礎となる *clone* ()システムコールの上に階層化されたライブラリ関数であり、以降は *sys_clone* と呼びます。 *sys_clone* の説明は、このページの終わりに向けて提供されます。
*fork* (2)とは異なり、これらの呼び出しにより、子プロセスは、メモリスペース、ファイル記述子のテーブル、シグナルハンドラのテーブルなど、実行コンテキストの一部を呼び出しプロセスと共有できます。 (このマニュアルページでは、「呼び出しプロセス」は通常「親プロセス」に対応することに注意してください。 ただし、以下の *CLONE_PARENT* の説明を参照してください。)
*clone* ()の主な用途は、スレッドを実装することです:共有メモリ空間で同時に実行されるプログラム内の複数の制御スレッド。

子プロセスが clone ()で作成されると、関数application fn _( arg_)が実行されます。 (これは、 fork (2)呼び出しの時点から子で実行が継続する fork (2)とは異なります。)_fn_引数は、最初に子プロセスによって呼び出される関数へのポインターです。その実行の。 _arg_引数は、_fn_関数に渡されます。

fn _( arg_)関数アプリケーションが戻ると、子プロセスは終了します。 _fn_によって返される整数は、子プロセスの終了コードです。 子プロセスは、 exit (2)を呼び出すか、致命的なシグナルを受信した後、明示的に終了することもできます。

_child_stack_引数は、子プロセスが使用するスタックの場所を指定します。 子プロセスと呼び出しプロセスはメモリを共有する可能性があるため、子プロセスを呼び出しプロセスと同じスタックで実行することはできません。 したがって、呼び出しプロセスは、子スタックのメモリ空間を設定し、この空間へのポインタを clone ()に渡す必要があります。 スタックは、Linuxを実行するすべてのプロセッサー(HP PAプロセッサーを除く)で下方に成長するため、_child_stack_は通常、子スタック用にセットアップされたメモリー空間の最上位アドレスを指します。

_flags_の下位バイトには、子が死んだときに親に送信される_終了シグナル_の番号が含まれます。 このシグナルが SIGCHLD' 以外の何かとして指定されている場合、親プロセスは wait (2)で子を待つときに WALL または ' WCLONE オプションを指定する必要があります。 シグナルが指定されていない場合、子プロセスが終了しても親プロセスはシグナルを受けません。

.

_flags_は、呼び出しプロセスと子プロセスの間で共有されるものを指定するために、次の定数の0個以上でビット単位の論理和をとることもできます。

Tag Description
*CLONE_PARENT *(since Linux 2.3.12)

If* CLONE_PARENT is set, then the parent of the new child (as returned by getppid*(2)) will be the same as that of the calling process.

  • CLONE_PARENT* が設定されていない場合、( *fork* (2)と同様に)子の親が呼び出しプロセスです。

これは、 getppid (2)によって返される親プロセスであり、子プロセスの終了時に通知されるため、 CLONE_PARENT が設定されている場合は、呼び出しプロセス自体ではなく、呼び出しプロセスの親であることに注意してください。通知されます。

*CLONE_FS *a

If* CLONE_FS is set, the caller and the child processes share the same file system information. This includes the root of the file system, the current working directory, and the umask. Any call to chroot*(2), chdir(2), or umask(2) performed by the calling process or the child process also affects the other process.

CLONE_FS が設定されていない場合、子プロセスは、 clone ()呼び出し時に呼び出しプロセスのファイルシステム情報のコピーを処理します。 いずれかのプロセスが後で実行する chroot (2)、 chdir (2)、 umask (2)の呼び出しは、他のプロセスに影響を与えません。

*CLONE_FILES *a

If* CLONE_FILES is set, the calling process and the child processes share the same file descriptor table. Any file descriptor created by the calling process or by the child process is also valid in the other process. Similarly, if one of the processes closes a file descriptor, or changes its associated flags (using the fcntl*(2) F_SETFD operation), the other process is also affected.

CLONE_FILES が設定されていない場合、子プロセスは clone ()の時点で呼び出しプロセスで開かれたすべてのファイル記述子のコピーを継承します。 (子の重複ファイル記述子は、呼び出しプロセスの対応するファイル記述子と同じオープンファイル記述( open (2)を参照)を参照します。)ファイル記述子を開いたり閉じたり、ファイル記述子フラグを変更する後続の操作、呼び出しプロセスまたは子プロセスのいずれかが実行しても、他のプロセスには影響しません。

*CLONE_NEWNS *(since Linux 2.4.19)

Start the child in a new namespace.

すべてのプロセスは名前空間に存在します。 プロセスの_namespace_は、そのプロセスから見たファイル階層を記述するデータ(マウントのセット)です。* CLONE_NEWNS フラグが設定されていない *fork (2)または clone (2)の後、子は親と同じ名前空間に住んでいます。 システム呼び出し mount (2)および umount (2)は、呼び出しプロセスの名前空間を変更します。したがって、同じ名前空間に存在するすべてのプロセスに影響しますが、異なる名前空間のプロセスには影響しません。

  • CLONE_NEWNS* フラグが設定されている *clone* (2)の後、クローンされた子は新しい名前空間で開始され、親の名前空間のコピーで初期化されます。 *CLONE_NEWNS* フラグを指定できるのは、特権プロセス(CAP_SYS_ADMIN機能を持つプロセス)のみです。 同じ *clone* ()呼び出しで *CLONE_NEWNS* と *CLONE_FS* の両方を指定することはできません。
*CLONE_SIGHAND *a

If* CLONE_SIGHAND is set, the calling process and the child processes share the same table of signal handlers. If the calling process or child process calls sigaction*(2) to change the behavior associated with a signal, the behavior is changed in the other process as well. However, the calling process and child processes still have distinct signal masks and sets of pending signals. So, one of them may block or unblock some signals using sigprocmask(2) without affecting the other process.

CLONE_SIGHAND が設定されていない場合、子プロセスは、 clone ()が呼び出された時点で、呼び出し元プロセスのシグナルハンドラーのコピーを継承します。 いずれかのプロセスが後で実行する sigaction (2)の呼び出しは、他のプロセスには影響しません。

Linux 2.6.0-test6以降、 CLONE_SIGHAND が指定されている場合、_flags_には CLONE_VM も含める必要があります。

*CLONE_PTRACE * If* CLONE_PTRACE is specified, and the calling process is being traced, then trace the child also (see ptrace*(2)).
*CLONE_UNTRACED *(since Linux 2.5.46) If* CLONE_UNTRACED is specified, then a tracing process cannot force CLONE_PTRACE* on this child process.
*CLONE_STOPPED *(since Linux 2.6.0-test2) If* CLONE_STOPPED is set, then the child is initially stopped (as though it was sent a SIGSTOP signal), and must be resumed by sending it a SIGCONT* signal.
*CLONE_VFORK *a

If* CLONE_VFORK is set, the execution of the calling process is suspended until the child releases its virtual memory resources via a call to execve*(2) or _exit(2) (as with vfork(2)).

CLONE_VFORK が設定されていない場合、呼び出しプロセスと子プロセスの両方が呼び出し後にスケジュール可能であり、アプリケーションは特定の順序で発生する実行に依存するべきではありません。

*CLONE_VM *a

If* CLONE_VM is set, the calling process and the child processes run in the same memory space. In particular, memory writes performed by the calling process or by the child process are also visible in the other process. Moreover, any memory mapping or unmapping performed with mmap*(2) or munmap(2) by the child or calling process also affects the other process.

CLONE_VM が設定されていない場合、子プロセスは clone ()の時点で呼び出し元プロセスのメモリ空間の別のコピーで実行されます。 fork (2)の場合のように、プロセスの1つによって実行されるメモリ書き込みまたはファイルマッピング/マッピング解除は、他のプロセスに影響しません。

*CLONE_PID *(obsolete) If* CLONE_PID* is set, the child process is created with the same process ID as the calling process. This is good for hacking the system, but otherwise of not much use. Since 2.3.21 this flag can be specified only by the system boot process (PID 0). It disappeared in Linux 2.5.16.
*CLONE_THREAD *(since Linux 2.4.0-test8)

If* CLONE_THREAD is set, the child is placed in the same thread group as the calling process. To make the remainder of the discussion of CLONE_THREAD* more readable, the term "thread" is used to refer to the processes within a thread group.

スレッドグループは、単一のPIDを共有する一連のスレッドのPOSIXスレッド概念をサポートするために、Linux 2.4で追加された機能でした。 内部的には、この共有PIDは、スレッドグループのいわゆるスレッドグループ識別子(TGID)です。 Linux 2.4以降、 getpid (2)を呼び出すと、呼び出し元のTGIDが返されます。

グループ内のスレッドは、(システム全体の)一意のスレッドID(TID)で区別できます。 新しいスレッドのTIDは、 clone ()の呼び出し元に返される関数結果として利用でき、スレッドは gettid (2)を使用して独自のTIDを取得できます。

  • CLONE_THREAD* を指定せずに *clone* ()を呼び出すと、結果のスレッドは、TGIDがスレッドのTIDと同じである新しいスレッドグループに配置されます。 このスレッドは、新しいスレッドグループの「リーダー」です。 *CLONE_THREAD* で作成された新しいスレッドは、 *clone* ()の呼び出し元と同じ親プロセス( *CLONE_PARENT* など)を持っているため、 *getppid* (2)の呼び出しはすべてのスレッドに同じ値を返します。スレッドグループ内。 *CLONE_THREAD* スレッドが終了すると、 *clone* ()を使用してスレッドを作成したスレッドには *SIGCHLD* (または他の終了)シグナルが送信されません。また、 *wait* (2)を使用してそのようなスレッドのステータスを取得することもできません。 (スレッドは_detached_と言われます。)

スレッドグループ内のすべてのスレッドが終了すると、スレッドグループの親プロセスに SIGCHLD (または他の終了)シグナルが送信されます。

スレッドグループ内のスレッドのいずれかが execve (2)を実行すると、スレッドグループリーダー以外のすべてのスレッドが終了し、新しいプログラムがスレッドグループリーダーで実行されます。

スレッドグループ内のスレッドの1つが fork (2)を使用して子を作成する場合、グループ内のすべてのスレッドはその子を wait (2)できます。

Linux 2.5.35以降、 CLONE_THREAD が指定されている場合、_flags_には CLONE_SIGHAND も含める必要があります。

シグナルは、 kill (2)を使用してスレッドグループ全体(つまりTGID)に送信されるか、 tgkill (2)を使用して特定のスレッド(つまりTID)に送信されます。

シグナルの処理とアクションはプロセス全体です。未処理のシグナルがスレッドに配信されると、スレッドグループのすべてのメンバーに影響(終了、停止、続行、無視)します。

各スレッドには、 sigprocmask (2)で設定された独自のシグナルマスクがありますが、シグナルは保留中の場合があります。プロセス全体(スレッドグループの任意のメンバーに配信可能)、 kill (2 );または、 tgkill (2)で送信された個々のスレッド用。 sigpending (2)を呼び出すと、プロセス全体で保留中のシグナルと、呼び出しスレッドで保留中のシグナルの和集合であるシグナルセットが返されます。

  • kill* (2)を使用してスレッドグループにシグナルを送信し、スレッドグループがシグナルのハンドラーをインストールしている場合、ハンドラーは、スレッドグループの任意の選択されていない1つのメンバーで呼び出されます。信号をブロックしました。 グループ内の複数のスレッドが *sigwaitinfo* (2)を使用して同じシグナルを受け入れるのを待っている場合、カーネルは *kill* (2)を使用して送信されたシグナルを受信するためにこれらのスレッドの1つを任意に選択します。
*CLONE_SYSVSEM *(since Linux 2.5.10) If* CLONE_SYSVSEM is set, then the child and the calling process share a single list of System V semaphore undo values (see semop*(2)). If this flag is not set, then the child has a separate undo list, which is initially empty.
*CLONE_SETTLS *(since Linux 2.5.32) The newtls parameter is the new TLS (Thread Local Storage) descriptor. (See* set_thread_area*(2).)
CLONE_PARENT_SETTID (since Linux 2.5.49) Store child thread ID at location parent_tidptr in parent and child memory. (In Linux 2.5.32-2.5.48 there was a flag CLONE_SETTID that did this.)
CLONE_CHILD_SETTID (since Linux 2.5.49) Store child thread ID at location child_tidptr in child memory.
*CLONE_CHILD_CLEARTID *(since Linux 2.5.49) Erase child thread ID at location child_tidptr in child memory when the child exits, and do a wakeup on the futex at that address. The address involved may be changed by the* set_tid_address*(2) system call. This is used by threading libraries.

sys_clone

*sys_clone* システムコールは、子の実行がコールのポイントから継続するという点で、 *fork* (2)により密接に対応します。 したがって、 *sys_clone* には_flags_引数と_child_stack_引数のみが必要です。これらの引数は *clone* ()と同じ意味を持ちます。 (これらの引数の順序は *clone* ()とは異なることに注意してください。)
*sys_clone* のもう1つの違いは、_child_stack_引数がゼロになる可能性があることです。この場合、コピーオンライトセマンティクスにより、いずれかのプロセスがスタックを変更するときに子がスタックページの個別のコピーを取得します。 この場合、正しい操作のために、 *CLONE_VM* オプションを指定しないでください。

Linux 2.5.49以降、システムコールには5つのパラメーターがあります。 2つの新しいパラメーターは、CLONE_PARENT_SETTIDが指定された場合に子スレッドIDが書き込まれる場所(親および子メモリー内)を指す_parent_tidptr_と、子スレッドIDが置かれる場所(子メモリー内)を指す_child_tidptr_です。 CLONE_CHILD_SETTIDが指定された場合に書き込まれます。

返り値

成功すると、子プロセスのスレッドIDが呼び出し元の実行スレッドに返されます。 失敗すると、呼び出し元のコンテキストに-1が返され、子プロセスは作成されず、_errno_が適切に設定されます。

エラー

Tag Description
EAGAIN Too many processes are already running.
EINVAL CLONE_SIGHAND *was specified, but CLONE_VM* was not. (Since Linux 2.6.0-test6.)
EINVAL CLONE_THREAD *was specified, but CLONE_SIGHAND* was not. (Since Linux 2.5.35.)
*EINVAL * Both* CLONE_FS and CLONE_NEWNS* were specified in flags.
*EINVAL * Returned by* clone*() when a zero value is specified for child_stack.
ENOMEM Cannot allocate sufficient memory to allocate a task structure for the child, or to copy those parts of the caller’s context that need to be copied.
EPERM CLONE_NEWNS was specified by a non-root process (process without CAP_SYS_ADMIN).
EPERM CLONE_PID was specified by a process other than process 0.

バージョン

libc5には clone ()のエントリはありません。 glibc2は、このマニュアルページで説明されている clone ()を提供します。

準拠

*clone* ()および *sys_clone* 呼び出しはLinux固有であり、移植を目的としたプログラムでは使用しないでください。

ノート

カーネル2.4.xシリーズでは、 CLONE_THREAD は通常、新しいスレッドの親を呼び出しプロセスの親と同じにしません。 ただし、カーネルバージョン2.4.7から2.4.18では、 CLONE_THREAD フラグは CLONE_PARENT フラグを暗黙指定しました(カーネル2.6と同様)。

しばらくの間、 CLONE_DETACHED (2.5.32で導入)がありました:親は子出口シグナルを望みません。 2.6.2では、これを CLONE_THREAD と一緒に指定する必要がなくなりました。 このフラグはまだ定義されていますが、効果はありません。 x86では、 clone ()はvsyscallからではなく、_int $ 0x80_から直接呼び出す必要があります。 IA-64では、異なるシステムコールが使用されます。

int __clone2(int (*fn)(void *), void *child_stack_base, size_t stack_size, int flags, void *arg, ... /*pid_t* pid, struct user_desc *tls ", pid_t *" ctid " */);"
*__ clone2* ()システムコールは、_child_stack_base_が子のスタック領域の最下位アドレスを指し、_stack_size_が_child_stack_base_が指すスタックのサイズを指定することを除いて、 *clone* ()と同じように動作します。

BUGS

NPTLスレッドライブラリを含むGNU Cライブラリのバージョンには、PIDのキャッシュを実行する getpid (2)のラッパー関数が含まれています。 そのようなライブラリに対してリンクされたプログラムでは、 CLONE_THREAD を使用してスレッドが作成されなかった(したがって、同じスレッドグループにない)場合でも、 getpid (2)の呼び出しは同じ値を返すことがあります。 真実を知るには、次のようなコードを使用する必要があるかもしれません

#include <syscall.h> pid_t mypid; mypid = syscall(SYS_getpid);

関連項目

[[File:]] image :http://www.finddevguides.com/images/next.gif [next] [[File:]]

広告

|  

[cols="^",]

|Advertisements