CLONE(2)

名前
__clone - 子プロセスを作成する

書式
#include <sched.h>

int __clone(int (*fn) (void *arg), void *child_stack, int flags, void *arg)

説明
__clone は fork(2) のように新しいプロセスを作成する。 fork(2) と違って __clone は子プロセス(child process)がメモリ空間、ファイル・ディスクリプターの テーブル、シグナル・ハンドラーのテーブルなどの実行コンテキストの一部を 親プロセスと共有することを可能にする。 __clone の主要な使用法はスレッド(threads)を実装することである: 一つのプログラムの中の複数のスレッドは共有されたメモリ空間に おいて協調して実行される。 子プロセスが作成された時に、関数 fn(arg) が実行される。 fn 引き数は子プロセスが実行を始める時に呼び出される 関数へのポインターである。 arg 引き数はそのまま fn 関数へと渡される。 fn(arg) 関数適用から返る時に、子プロセスは終了する。 fn によって返された整数は子プロセスの終了コードとなる。 子プロセスは明示的に exit(1) を呼んだり、致命的なシグナルを受けた場合にも終了する。 child_stack 引き数は子プロセスによって使用されるスタックの位置を指定する。 子プロセスと親プロセスはメモリを共有するため、一般に子プロセスは 親プロセスと同じスタックで実行することができない。 このため親プロセスは子プロセスのスタックのためのメモリ空間を設定 して、この空間へのポインターを __clone へ渡さなければならない。 Linux が走っている(HP PA プロセッサーを除く)全てのプロセッサでは スタックは下方へと成長する。それで child_stack は大抵、子プロセスのスタックのために設定したメモリ空間の一番大きい アドレスへのポインターである。 flags の下位バイトは子プロセスが死んだ場合に親プロセスへと送られる シグナル番号を指定する。 flags はさらに以下の内容のいくつかのビット OR(bitwise-or)で、 親プロセスと子プロセスの間で何を共有するかを指定するために使用する。

CLONE_VM
    CLONE_VM が設定された場合、親プロセスと子プロセスは同じメモリ空間で実行される。 特に親プロセスや子プロセスによってメモリに書き込まれた内容は他のプロセス によっても見ることができる。さらに、 子プロセスや親プロセスが mmap(2) や munmap(2) を使ってメモリをマップしたりアンマップした場合、 それは他のプロセスへも影響する。 CLONE_VM が設定されていない場合、子プロセスは __clone が実行された時点での親プロセスのメモリ空間をコピーした 別のメモリ空間で実行される。 あるプロセスで行なわれたメモリへの書き込み、 ファイルのマップ/アンマップは fork(2) の場合と同様、他には影響しない。

CLONE_FS
    CLONE_FS が設定された場合、親プロセスと子プロセスが同じファイル・システム情報を 共有する。これにはファイルシステムのルート(root)や現在の ワーキング・ディレクトリ(current working directory)や umask が含まれる。 親プロセスや子プロセスによって行なわれた全ての chroot(2), chdir(2), umask(2) は他のプロセスにも影響する。 CLONE_FS が設定されていない場合、子プロセスは __clone が実行された時点での親プロセスのファイル・システム情報のコピーを 使用する。 それ以後、あるプロセスによって行なわれた chroot(2),chdir(2),umask(2) コールは他には影響しない。

CLONE_FILES
    CLONE_FILES が設定された場合、親プロセスと子プロセスはファイル・ディスクリプターの テーブルを共有する。ファイル・ディスクリプターは子プロセスと親プロセス において常に同じファイルを参照する。親プロセスや子プロセスによって 作成された全てのファイル・ディスクリプターは他のプロセスにおいても 有効である。同様に、あるプロセスがファイル・ディスクリプターの クローズ(close)や、設定されたフラグの変更を行なった場合は他のプロセスに も影響する。 CLONE_FILES が設定されていない場合、子プロセスは __clone が実行された時点での親プロセスがオープン(open)している全ての ファイル・ディスクリプターのコピーを継承する。 それ以後、あるプロセスによって行なわれたファイル・ディスクリプターに 対して行なわれた操作は他には影響しない。

CLONE_SIGHAND
    CLONE_SIGHAND が設定された場合、親プロセスと子プロセスは同じシグナル・ハンドラーの テーブルを共有する。親プロセスまたは子プロセスが sigaction(2) コールして、シグナルに関連づけられた動作を変更した場合、同様に 他のプロセスの動作も変更される。一方で、親プロセスと子プロセスは 個別のシグナル・マスク(signal mask)と解決中のシグナルの集合を持っている。 それで、プロセスは他のプロセスに影響を与えることなしに sigprocmask(2) を使用してシグナルを禁止(block)したり許可(unblock)したりできる。 CLONE_SIGHAND が設定されていない場合、子プロセスは __clone がコールされた時点での親プロセスのシグナル・ハンドラーのコピーを継承する。 それ以後、あるプロセスによって行なわれた sigaction(2) コールは他のプロセスには影響しない。

CLONE_PID
    CLONE_PID が設定された場合、子プロセスは親プロセスと同じプロセス ID で作成される。 CLONE_PID が設定されていない場合、子プロセスは独立したプロセス ID を持ち、 親プロセスとは区別される。

返り値
成功した場合、親の実行スレッドには子プロセスの PID が返される。 失敗した場合、 親のコンテキストには -1 が返され子プロセスは作成されない。 さらに errno が適切に設定される。

エラー

EAGAIN
    すでに走っているプロセスが多過ぎる。

ENOMEM
    __clone 子プロセスのために確保すべきタスク構造体や、親のコンテキストの 一部ををコピーするのに必要なメモリを割り当てることができない。

バグ
カーネルのバージョン 2.1.97 では、 CLONE_PID フラグを使用してはならない。カーネルの他の部分や多くの システム・ソフトウェアがプロセス ID には重複がないことを 仮定しているためにである。 libc version 5 には __clone のためのエントリが存在しない。libc 6 (またの名を glibc2)には このマニュアル・ページに記述してある __clone を提供する。

準拠
__clone コールは Linux 特有であり、移植性が必要なプログラムでは使用しては ならない。スレッドを使用したアプリケーションのプログラミグには LinuxThreads ライブラリのような、POSIX 1003.1c thread API を実装した ライブラリを使用した方が良い。 pthread_create(3thr) を参照すること。 こマニュアル・ページはカーネル 2.0.x と 2.1.x および glibc 2.0.x に 対応している。

関連項目
fork(2), pthread_create(3thr).