VFORK
Section: Linux Programmer's Manual (2)
Updated: 2007-07-26
Index
JM Home Page
roff page
名前
vfork - 子プロセスを生成し親プロセスを停止させる
書式
#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void);
glibc 向けの機能検査マクロの要件
(feature_test_macros(7)
参照):
vfork():
_BSD_SOURCE || _XOPEN_SOURCE >= 500
説明
規格の説明
(SUSv2 / POSIX ドラフトより引用)
vfork()
関数は
fork(2)
と同じ働きをするが、
vfork()
で作成されたプロセスが
vfork()
からの返り値を格納している
pid_t
型の変数以外を変更したり、
vfork()
を呼び出している関数から return したり、
_exit(2)
や
exec(3)
族の関数をコールする前に他の関数をコールした場合の動作が
未定義であるという点が異なる。
LINUX での説明
vfork()
は
fork(2)
と全く同じように呼び出したプロセスの子プロセスを生成する。
詳しい説明と返り値、エラーについては
fork(2)
を参照すること。
vfork()
は
clone(2)
の特殊な場合である。
親プロセスのページテーブルのコピーを行わずに新しいプロセスを
作成するために使用する。これは性能に敏感なアプリケーションにおいて
子プロセスを生成してすぐに
execve(2)
する場合に有用かもしれない。
vfork()
は
fork(2)
と違い、子プロセスが
execve(2)
または
_exit(2)
をコールするまで親プロセスを停止 (suspend) させる。
子プロセスが
execve(2)
を実行するまでは、子プロセスはスタックを含めて全てのメモリを
親プロセスと共有する。
子プロセスは現在の関数から return してはならず、
exit(3)
もコールしてはならないが、
_exit(2)
ならばコールしてもよい。
シグナルハンドラは継承されるが、共有はされない。
親プロセスへのシグナルは子プロセスが親プロセスのメモリを
解放した後に到着する。
歴史的な説明
Linux において
fork(2)
は書き込み時コピー (copy-on-write) ページを使用して実装されている。
そのため
fork(2)
を使用することによって被る損害は親プロセスのページ・テーブルを
複製するために必要な時間とメモリだけである。
しかしながら、忌しき昔には
fork(2)
は呼び出したプロセスのデータ空間の全てのコピーしていたが、
これはしばしば不必要であった。なぜなら、たいていはすぐ後に
exec(3)
を実行していたからである。
この場合の効率を上げるために BSD は
vfork()
システムコールを導入して親プロセスのアドレス空間を完全にコピー
するかわりに、
execve(2)
をコールするか exit が起きるまで親プロセスのメモリと制御スレッド
を借りるようにした。
親プロセスは子プロセスがその資源を使用している間は停止された。
vfork()
は使いにくいものであった: 例えば、親プロセスの変数を変更しな
いようにするためにはどの変数がレジスタに保持されているかを知らな
ければならなかった。
準拠
4.3BSD, POSIX.1-2001.
vfork()
コールは他のオペレーティング・システムの同名のコールと
ちょっと似ているかもしれない。規格が
vfork()
に要求していることは、
fork(2)
に要求していることよりは弱い。したがって、
両者を同じものとして実装しても、規格に準拠していることになる。
特にプログラマーは
execve(2)
または
_exit(2)
を実行するまで親プロセスが停止していることや、メモリを共有するこ
とによる特殊な動作をあてにすべきではない。
注意
Linux での注意
pthread_atfork(3)
を使って設定された fork ハンドラは
NPTL スレッドライブラリコールを採用したマルチスレッドプログラムでは
呼び出されない。一方、LinuxThreads スレッドライブラリを使った
プログラムでは、fork ハンドラは呼び出される。
(Linux のスレッドライブラリの説明は
pthreads(7)
を参照。)
歴史
vfork()
システムコールは 3.0BSD に現われた。
4.4BSD において
fork(2)
の同義語となったが、NetBSD では再び導入された。
http://www.netbsd.org/Documentation/kernel/vfork.html を参照。
Linux では 2.2.0-pre6 あたりまでは
fork(2)
と等価であった。(i386 では) 2.2.0-pre9 から (他のアーキテクチャでは
少し遅れて) 独立したシステムコールとなった。
glibc でのサポートは glibc-2.0.112 で追加された。
バグ
Linux がこの過去の亡霊を復活させたことは、むしろ不幸と言うべきである。
BSD のマニュアルには、
「このシステムコールは妥当なシステム共有機構が実装された場合には
削除される。ユーザは
vfork()
のメモリ共有機能に依存するべきではない。何故ならば、このシステムコール
が削除された場合には、それは
fork(2)
の同義語とされるからである。」と書かれている。
シグナルの扱いの詳細は不明瞭でシステムごとに異っている。
BSD のマニュアルには、
「デッドロック状態になる可能性があるので
vfork()
の途中の子プロセスに
SIGTTOU
や
SIGTTIN
シグナルを送信してはならない;
さらに出力や
ioctl
は許されるが、入力を試みた場合には結果はファイル終端 (EOF) になる。」
と書かれている。
関連項目
clone(2),
execve(2),
fork(2),
unshare(2),
wait(2)
Index
- 名前
-
- 書式
-
- 説明
-
- 規格の説明
-
- LINUX での説明
-
- 歴史的な説明
-
- 準拠
-
- 注意
-
- Linux での注意
-
- 歴史
-
- バグ
-
- 関連項目
-
This document was created by
man2html,
using the manual pages.
Time: 04:32:10 GMT, November 19, 2007