fork()とvfork()の違いについてもっと知りたいです。マニュアルページをよく理解できません。
また、同僚の一人がコメントを明確にしたいと思います。」現在、Linuxにはvfork()はありません。呼び出しても、内部的には fork() を呼び出すことになります。」。
答え1
マニュアルページは、一般的に簡潔な参照文書です。ウィキペディア概念の説明を見つけるのに最適な場所です。
Forkはプロセスをコピーします。つまり、親プロセスとほぼ同じ子プロセスを作成します(最も明白な違いは、新しいプロセスのプロセスIDが異なることです)。特に、フォークは(概念的に)親プロセスのすべてのメモリをコピーする必要があります。
これはかなりコストがかかるため、コピーを必要としない一般的な特殊なケースを処理するために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を含むほとんどの最新システムはフォームを使用しています。書き込み中のコピーここで、プロセスメモリのページは呼び出されたときにコピーされず、fork
代わりに親または子がページに最初に書き込まれるときにコピーされます。つまり、各ページは最初に共有され、書き込みプロセスが同じ仮想アドレスを持つ新しい物理ページを取得するまで共有されたままになります。書き込み中のコピーは、可能であればfork
コピーが作成されないため、vfork をほとんど無用にします。vfork
Linuxはvforkを維持します。システムfork
コールは物理メモリをコピーしなくても、プロセスの仮想メモリテーブルをコピーする必要がありますvfork
。ほとんどのアプリケーションでは、パフォーマンスの向上は無視できます。
答え2
fork()
システムコールとはvfork()
異なります。
システムfork()
コールは、独立したメモリを持つ2つの同じプロセスを生成します。システムvfork()
コールは、同じメモリを共有する2つのプロセスを生成します。
親プロセスはvfork()
子プロセスが終了するのを待ちます。親はプログラムが共有する変数を継承します。したがって、子プロセスが呼び出された後でも、子プロセス内で変更されたすべての変数はまだ親プロセス内で変更されます。
詳細についてはクリックしてください。ここ