other versions
other sections
CLONE(2) | Linux Programmer's Manual | CLONE(2) |
名前¶
clone, __clone2 - 子プロセスを作成する書式¶
#define _GNU_SOURCE /* feature_test_macros(7) 参照 */ #include <sched.h> int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
説明¶
clone() は fork(2) と同じような方法で新しいプロセスを作成する。 clone() には、ライブラリ関数とその下層にあたる clone() システムコールが存在する。以下の説明では、システムコールの方を sys_clone と表すこととする。 sys_clone に関する説明はこのマニュアルの最後の方にある。- CLONE_CHILD_CLEARTID (Linux 2.5.49 以降)
- 子プロセスが終了したときに子プロセスのメモリ内の ctid が指す場所にある子プロセスのスレッド ID を消去し、 そのアドレスで futex を wake (起床) させる。 このアドレスは set_tid_address(2) システムコールで変更することができる。 この機能はスレッドライブラリで使用される。
- CLONE_CHILD_SETTID (Linux 2.5.49 以降)
- 子プロセスのメモリ内の ctid が指す場所に子プロセスのスレッド ID を格納する。
- CLONE_FILES
- CLONE_FILES
が設定された場合、呼び出し元のプロセスと子プロセスはファイルディスクリプタの
テーブルを共有する。
呼び出し元プロセスとその子プロセスの一方が作成した
ファイルディスクリプタは、もう一方においても有効である。
同じように、一方のプロセスがファイルディスクリプタを閉じたり、
( fcntl(2) F_SETFD
操作を使って)
ディスクリプタに関連するフラグを変更したりすると、
もう一方のプロセスにも影響する。
- CLONE_FS
- CLONE_FS
が設定された場合、呼び出し元のプロセスと子プロセスが同じファイル・システム
情報を共有する。ファイル・システム情報は、ファイル・システムのルート
(root)、
カレント・ワーキング・ディレクトリ
(current working directory) や umask
などである。
呼び出し元のプロセスや子プロセスのどちらか一方によって
chroot(2), chdir(2), umask(2)
が呼び出されると、もう一方のプロセスにも影響が及ぶ。
- CLONE_IO (Linux 2.6.25 以降)
- CLONE_IO
が設定された場合、新しいプロセスは呼び出し元のプロセスと
I/O
コンテキストを共有する。
このフラグが設定されていない場合には、
( fork(2) の場合と同様)
新しいプロセスは自分専用の
I/O
コンテキストを持つ。
- CLONE_NEWIPC (Linux 2.6.19 以降)
- CLONE_NEWIPC
が設定された場合、新しい
IPC 名前空間 (namespace)
でプロセスを作成する。
このフラグが設定されていない場合、
( fork(2) の場合と同様)
呼び出し元のプロセスと同じ
IPC
名前空間でプロセスが
作成される。
このフラグは、コンテナの実装での使用を意図して用意されたものである。
- CLONE_NEWNET (Linux 2.6.24 以降)
- (このフラグの実装は、Linux
2.6.29
あたりまでに完成した。)
- CLONE_NEWNS (Linux 2.4.19 以降)
- 子プロセスを新しいマウント名前空間
(mount namespace) で開始する。
- CLONE_NEWPID (Linux 2.6.24 以降)
- CLONE_NEWPID
が設定された場合、新しい
PID
名前空間でプロセスを作成する。
このフラグが設定されていない場合、
( fork(2) の場合と同様)
呼び出し元のプロセスと同じ
PID 名前空間で
プロセスが作成される。
このフラグは、コンテナの実装での使用を意図して用意されたものである。
- CLONE_NEWUTS (Linux 2.6.19 以降)
- CLONE_NEWUTS
が設定された場合、新しい
UTS
名前空間でプロセスを作成する。
新しい UTS
名前空間の識別子の初期値は、呼び出し元のプロセスの
UTS
名前空間の識別子を複製したものとなる。
このフラグが設定されていない場合、
( fork(2) の場合と同様)
呼び出し元のプロセスと同じ
UTS 名前空間で
プロセスが作成される。
このフラグは、コンテナの実装での使用を意図して用意されたものである。
- CLONE_PARENT (Linux 2.3.12 以降)
- CLONE_PARENT
が設定された場合、新しい子供の
( getppid(2) で返される)
親プロセスは呼び出し元のプロセスの親プロセスと同じになる。
- CLONE_PARENT_SETTID (Linux 2.5.49 以降)
- 親プロセスと子プロセスのメモリ内の ptid が指す領域に子プロセスのスレッド ID を格納する。 (Linux 2.5.32-2.5.48 では、 同じことをする CLONE_SETTID というフラグが存在した。)
- CLONE_PID (廃止予定)
- CLONE_PID が設定された場合、子プロセスは呼び出し元のプロセスと同じプロセス ID で作成される。これはシステムをハッキングするのには便利だが、 それ以外にはあまり使われない。 Linux 2.3.21 以降では、 システムのブートプロセス (PID 0) だけがこのフラグを指定できる。 Linux 2.5.16 で削除された。
- CLONE_PTRACE
- CLONE_PTRACE が指定され、かつ呼び出し元のプロセスが追跡 (trace) されていた場合、子プロセスも 同様に追跡される。 ( ptrace(2) を参照のこと)
- CLONE_SETTLS (Linux 2.5.32 以降)
- newtls 引き数は、新しい TLS (Thread Local Storage) ディスクリプタである。 ( set_thread_area(2) を参照のこと)
- CLONE_SIGHAND
- CLONE_SIGHAND
が設定された場合、呼び出し元のプロセスと子プロセスは同じシグナル・ハン
ドラのテーブルを共有する。呼び出し元のプロセスまたは子プロセスのどちらかが
sigaction(2)
を呼び出してシグナルに対応する動作を変更した場合、
もう一方のプロセスのシグナル動作も変更される。
但し、呼び出し元のプロセスと子プロセスは、
プロセス毎に、シグナル・マスク
(signal mask)
と処理待ちシグナルの集合
を持っている。このため、あるプロセスは、
sigprocmask(2)
を使用して、もう一方のプロセスに影響を与えずに
シグナルを禁止 (block)
したり許可 (unblock)
したりできる。
- CLONE_STOPPED (Linux 2.6.0-test2 以降)
- CLONE_STOPPED
が設定されると、子プロセスは最初
( SIGSTOP
シグナルを送られたかのように)
停止した状態となる。
子プロセスを再開させるには
SIGCONT
シグナルを送信しなければならない。
- CLONE_SYSVSEM (Linux 2.5.10 以降)
- CLONE_SYSVSEM がセットされると、子プロセスと呼び出し元プロセスは一つの System V セマフォのアンドゥ値リスト ( semop(2) 参照) を共有する。このフラグがセットされていなければ、 子プロセスは独自のアンドゥリストを持つ (リストの初期値は空である)。
- CLONE_THREAD (Linux 2.4.0-test8以降)
- CLONE_THREAD
が設定された場合、子プロセスは呼び出し元のプロセスと同じスレッド・グループに
置かれる。 CLONE_THREAD
についての以降の議論を読みやすくするため、
「スレッド」という用語はスレッド・グループの中のプロセスを
参照するのに使うこととする。
- CLONE_UNTRACED (Linux 2.5.46 以降)
- CLONE_UNTRACED が指定されると、 trace を行っているプロセスは この子プロセスに CLONE_PTRACE を適用することができない。
- CLONE_VFORK
- CLONE_VFORK
が設定された場合、 (
vfork(2) と同様に)
子プロセスが execve(2)
または _exit(2)
によって仮想メモリを解放するまで、呼び出し元のプロセスの実行は停止される。
- CLONE_VM
- CLONE_VM
が設定された場合、呼び出し元のプロセスと子プロセスは同じメモリ空間で
実行される。特に、呼び出し元のプロセスや子プロセスの一方がメモリに
書き込んだ内容はもう一方のプロセスからも見ることができる。さらに、
子プロセスや呼び出し元のプロセスの一方が
mmap(2) や munmap(2)
を使ってメモリをマップしたりアンマップした場合、
もう一方のプロセスにも影響が及ぶ。
sys_clone¶
sys_clone システムコールは、より fork(2) に近いかたちになっており、子プロセスの実行が呼び出しが行われた場所から 続けられる。 そのため、 sys_clone が必要とする引き数は flags と child_stack だけであり、それらは clone() と同じ意味を持つ (これらの引き数の順番は clone() とは異なることに注意せよ)。返り値¶
成功した場合、呼び出し元の実行スレッドには子プロセスのスレッドID が返される。 失敗した場合、 呼び出し元のコンテキストには -1 が返され、子プロセスは 作成されず、 errno が適切に設定される。エラー¶
- EAGAIN
- すでに実行中のプロセスが多すぎる。
- EINVAL
- CLONE_SIGHAND が指定されていたが、 CLONE_VM が指定されていなかった。 (Linux 2.6.0-test6 以降)
- EINVAL
- CLONE_THREAD が指定されていたが、 CLONE_SIGHAND が指定されていなかった。 (Linux 2.5.35 以降)
- EINVAL
- CLONE_FS と CLONE_NEWNS の両方が flags に指定された。
- EINVAL
- CLONE_NEWIPC と CLONE_SYSVSEM の両方が flags に指定された。
- EINVAL
- CLONE_NEWPID と CLONE_THREAD の両方が flags に指定された。
- EINVAL
- child_stack にゼロを指定した場合に clone() が返す。
- EINVAL
- flags に CLONE_NEWIPC が指定されたが、カーネルでオプション CONFIG_SYSVIPC と CONFIG_IPC_NS が有効になっていなかった。
- EINVAL
- flags に CLONE_NEWNET が指定されたが、カーネルでオプション CONFIG_NET_NS が有効になっていなかった。
- EINVAL
- flags に CLONE_NEWPID が指定されたが、カーネルでオプション CONFIG_PID_NS が有効になっていなかった。
- EINVAL
- flags に CLONE_NEWUTS が指定されたが、カーネルでオプション CONFIG_UTS が有効になっていなかった。
- ENOMEM
- 子プロセスのために確保すべきタスク構造体や、呼び出し元のコンテキストの 一部をコピーするのに必要なメモリを十分に割り当てることができない。
- EPERM
- 非特権プロセス (CAP_SYS_ADMIN を持たないプロセス) が CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS を指定した。
- EPERM
- PID が 0 以外のプロセスによって CLONE_PID が指定された。
バージョン¶
libc5 には clone() はない。glibc2 では clone() が提供されており、このマニュアルページに記載の通りである。準拠¶
clone() と sys_clone コールは Linux 特有であり、移植を考慮したプログラムでは使用すべき ではない。注意¶
カーネル 2.4.x 系列では、一般的には CLONE_THREAD フラグを指定しても新しいスレッドの親を 呼び出し元プロセスの親と同じにはしない。 しかし、バージョン 2.4.7〜2.4.18 のカーネルでは、 (カーネル 2.6 と同じように) CLONE_THREAD フラグを指定すると、 暗黙のうちに CLONE_PARENT フラグを指定したことになる。int __clone2(int (*fn)(void *), void *child_stack_base, size_t stack_size, int flags, void *arg, ... /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );__clone2() システムコールは clone() と同じように動作するが、以下の点が異なる: child_stack_base は子プロセスのスタックエリアの最小のアドレスを指し、 stack_size は child_stack_base が指し示すスタックエリアの大きさを示す。
バグ¶
NPTL スレッド・ライブラリを含んでいる GNU C ライブラリのいくつかのバージョン には、 getpid(2) のラッパー関数が含まれており、このラッパー関数は PID をキャッシュする。 このキャッシュ処理が正しく動作するためには glibc の clone() のラッパー関数での助けが必要だが、現状の実装では、 ある状況下においてキャッシュが最新とならない可能性がある。 特に、 clone() の呼び出し直後にシグナルが子プロセスに配送された場合に、 そのシグナルに対するハンドラ内で getpid(2) を呼び出すと、それまでに clone のラッパー関数が子プロセスの PID キャッシュを 更新する機会が得られていなければ、呼び出し元プロセス ("親プロセス") の PID が 返される可能性がある。 (この議論では、子プロセスが CLONE_THREAD を使って作成された場合のことは無視している。 子プロセスが CLONE_THREAD を作って作成された場合には、 呼び出し元と子プロセスは同じスレッド・グループに属すので、 getpid(2) は子プロセスと clone() を呼び出したプロセスで同じ値を返すのが「正しい」。 キャッシュが最新とならない問題 (stale-cache problem) は、 flags に CLONE_VM が含まれている場合にも発生しない。) 本当の値を得るためには、次のようなコードを使う必要があるかもしれない。#include <syscall.h> pid_t mypid; mypid = syscall(SYS_getpid);
関連項目¶
fork(2), futex(2), getpid(2), gettid(2), set_thread_area(2), set_tid_address(2), tkill(2), unshare(2), wait(2), capabilities(7), pthreads(7)この文書について¶
この man ページは Linux man-pages プロジェクトのリリース 3.41 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2011-09-08 | Linux |