基本的なプロセス生成メカニズムがフォークされるのはなぜですか?

基本的なプロセス生成メカニズムがフォークされるのはなぜですか?

プロセスを生成するためのUNIXシステムコールfork()は、親プロセスをコピーして子プロセスを生成します。私が理解することは、ほとんどの場合、子プロセスのメモリ空間(テキストセグメントを含む)を置き換えるためにexec()を呼び出すことに従うことです。 fork()から親のメモリスペースをコピーすることは私にとって常に無駄なようです。 (メモリセグメントを書き込み中にコピー(つまり、ポインタのみコピー)することで無駄を最小限に抑えることができることを知っていますが)。とにかく、プロセスの作成にこのような反復的なアプローチが必要な理由を知っている人はいますか?

答え1

インターフェイスを簡素化することです。fork交換はexecWindowsに似ています。プロセスの作成機能。どのくらいのパラメータがあるかを確認してくださいCreateProcess。その多くは、より多くのパラメータを持つ構造です。このためですすべて新しいプロセスのための制御権CreateProcessCreateProcessユーザーによるプロセスの作成そしてログインを使用したプロセスの作成

このfork/execモデルでは、これらのパラメータはすべて必要ありません。代わりに、プロセスの一部のプロパティがに保存されますexec。これにより、fork必要なプロセス属性を変更できます(通常使用するのと同じ機能を使用)。それから exec。 Linuxにはパラメータがなく、実行するプログラム、そのプログラムに提供されるコマンドライン、および環境の3つしかforkありません。execve(他の関数もありますが、一般的なユースケースを単純化するためにCライブラリが提供するラッパーexecだけです。)execve

別の現在のディレクトリを使用してプロセスを開始したい場合 :fork、、、。chdirexec

stdin/stdout: をリダイレクトするには、forkファイルを閉じるか開きますexec

ユーザーを切り替えるには:fork、、、setuidexec

これらすべては必要に応じて組み合わせることができます。誰かが新しいプロセス属性を思いついたら、およびforkを変更する必要はありませんexec

Larskが述べたように、ほとんどの最新のUnixは書き込み中にコピーを使用するため、fork関連するオーバーヘッドはあまりありません。

答え2

cjmの答えに加えて、Single Unix仕様ではvfork()。この関数はexec関数系列を呼び出すか_exit()

したがって、動作定義の唯一の用途は次のとおりです。

pid_t ret = vfork();
if(ret == 0)
{
    exec(...);
    _exit(EXIT_FAILURE); //in case exec failed for any reason.
}

それで、それは何をしますかvfork?それは安いですfork。書き込み中にコピーのない実装で作成されたプロセスは、元のプロセスとメモリスペースを共有します(したがって、未定義の動作)。書き込み中のコピー実装では、書き込み中のコピー実装が高速であるため、vfork同じことが許可されます。fork()

新しいプロセスを直接生成するオプションのposix_spawn関数(および関数)もあります。posix_spawnpforkまた、ライブラリ呼び出しを使用して実装することもでき、サンプルexec実装も提供されています。)

関連情報