を呼び出すvfork()
と、新しいプロセスが作成され、その新しいプロセスは、スタックを除いて親プロセスのプロセスイメージを借用します。子プロセスには独自の新しいスタックスターが与えられますがreturn
、を呼び出した関数からは許可されませんvfork()
。
子が実行されている間、子は親のアドレス空間を借用したため、親プロセスはブロックされます。
何をするかに関係なく、スタックにアクセスするすべてのものは、子のプライベートスタックのみを変更します。ただし、グローバルデータを変更すると、共通データが変更されるため、親にも影響します。
グローバルデータを変更するものは次のとおりです。
呼び出すと_exit()
(重要、決してを呼び出さないexit()
)、子は終了し、制御は親に戻されます。
exec*()
ファミリから関数を呼び出すと、新しいアドレス空間が、新しいプログラムコード、新しいデータ、および親のスタックの一部で作成されます(以下を参照)。これが準備ができると、子は子からアドレス空間を借用しなくなり、独自のアドレス空間を使用します。
コントロールは親に戻されます。これは、そのアドレススペースが別のプロセスで使用されなくなったためです。
重要:Linuxでは、実際のvfork()
実装はありません。Linuxは、1988年にSunOS-4.0によって導入さvfork()
れたコピーオンライトfork()
コンセプトに基づいて実装しています。ユーザーがを使用しているとユーザーに信じさせるためにvfork()
、Linuxは共有データをセットアップし、子が呼び出さなかったときに親を一時停止する_exit()
か、exec*()
関数の1つを一時停止します。
したがって、Linuxではvfork()
、カーネルで子のアドレス空間記述を設定する必要がないというメリットはありません。その結果、vfork()
はより速くありませんfork()
。実際のシステムを実装するシステムvfork()
では、- 、最近、およびfork()
を使用するシェルのパフォーマンスよりも通常3倍速く、パフォーマンスに影響します。vfork()
ksh93
Bourne Shell
csh
edの子exit()
から呼び出してはならない理由は、を呼び出す前の時点からフラッシュされていないデータがある場合に備えてstdio vfork()
をexit()
フラッシュするためvfork()
です。これは、奇妙な結果を引き起こす可能性があります。
ところで:のposix_spawn()
上に実装されているvfork()
ためvfork()
、OSから削除されません。Linuxが使用していないことを述べてきたvfork()
ためposix_spawn()
。
スタックについては、ドキュメントがほとんどありません。Solarisのマニュアルページに次のように記載されています。
The vfork() and vforkx() functions can normally be used the
same way as fork() and forkx(), respectively. The calling
procedure, however, should not return while running in the
child's context, since the eventual return from vfork() or
vforkx() in the parent would be to a stack frame that no
longer exists.
したがって、実装は好きなように実行できます。Solarisの実装では、関数呼び出しのスタックフレームに共有メモリを使用しますvfork()
。親からスタックの古い部分へのアクセスを許可する実装はありません。