回答:
通常、マニュアルページは簡潔なリファレンスドキュメントです。ウィキペディアは、概念的な説明を参照するのに適した場所です。
Forkはプロセスを複製します。親プロセスとほとんど同じ子プロセスを作成します(最も明らかな違いは、新しいプロセスのプロセスIDが異なることです)。特に、forkは(概念的に)すべての親プロセスのメモリをコピーする必要があります。
これはかなりコストがかかるため、vforkは、コピーが不要な一般的な特殊なケースを処理するために考案されました。多くの場合、子プロセスが最初に行うことは新しいプログラムイメージをロードすることであるため、これが発生します。
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
execve
コールのロード新しい実行可能プログラム、およびこれは、新たな実行可能ファイルのコードと新鮮なデータメモリによって、プロセスのコードとデータメモリを置き換えます。そのため、作成されfork
たメモリコピー全体はまったく役に立ちませんでした。
したがって、vfork
呼び出しが考案されました。メモリのコピーは作成しません。したがってvfork
、安価ですが、子プロセス内のプロセスのスタックまたはヒープスペースにアクセスしないようにする必要があるため、使用するのは困難です。親プロセスが実行を続けるため、読み取りでさえ問題になる可能性があることに注意してください。たとえば、このコードは壊れています(子または親が最初にタイムスライスを取得するかどうかによって機能する場合と機能しない場合があります)。
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
vforkの発明以来、より良い最適化が考案されました。Linuxを含む最新のシステムのほとんどは、copy-on-writeの形式を使用します。プロセスメモリ内のページは、fork
呼び出し時にはコピーされませんが、後で親または子が最初にページに書き込むときにコピーされます。つまり、各ページは共有として開始され、いずれかのプロセスがそのページに書き込むまで共有されたままになります。書き込みを行うプロセスは、新しい物理ページを取得します(同じ仮想アドレスを使用)。Copy-on-writeを使用すると、vforkはほとんど使用できなくなります。使用可能なfork
場合にvfork
はコピーが作成されないためです。
Linuxはvforkを保持します。fork
システムコールはまだそれが実際のメモリをコピーしていない場合でも、プロセスの仮想メモリテーブルのコピーを作成する必要があります。vfork
これをする必要さえありません。ほとんどのアプリケーションでは、パフォーマンスの向上はごくわずかです。
fork
後続のコピーオンライトコピーが2つのプロセスのうちの1つだけに影響するように、個別の仮想メモリマッピングを作成する必要があります。