デフォルトのプロセス作成メカニズムがフォークするのはなぜですか?


46

プロセス作成のためのUNIXシステムコールfork()は、親プロセスをコピーして子プロセスを作成します。私の理解では、これにはほとんど常にexec()の呼び出しが続き、子プロセスのメモリスペース(テキストセグメントを含む)を置き換えます。fork()で親のメモリ空間をコピーすることは常に無駄に思えました(ただし、メモリセグメントをコピーオンライトにするとポインタのみがコピーされるため、無駄を最小限に抑えることができます)。とにかく、プロセスの作成にこの複製アプローチが必要な理由を誰もが知っていますか?


3
fork(2)Linux のマニュアルページには次のようUnder Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child. に書かれていることに注意してください。
ラースク

4
オリジナルのPDP-11 Unixは本当に、分岐したプロセスのすべてのバイトをコピーしました。しかし、実行可能ファイルは64 KBしかなく、データは最大で64 KBしかありませんでした。 1990年頃以降のすべてのunixおよびunix-a-likeにはコピーオンライトのテキストセグメントがあったため、本や記事が「フォークのパフォーマンスの問題」を広める理由はわかりません。
ブルースエディガー

現在、forkはvfork(openbsd.org/cgi-bin/…)と同様の方法で実装されています。効率的です、心配しないでください。
アキ

また、forkの後に実行しない(または、少なくともすぐには実行しない)多くの使用法があることに注意してください。パイプとWebサーバーを考えてください。
jfg956

遅いかもしれません。しかし、@ cjmがMicrosoftがCreateProcessを使用する代替案を見ると言うように、CreateProcessが遅いため、スレッドを早期に実装しなければなりませんでした(リードする唯一のものである可能性があります)。(select壊れていたためスレッドも必要でしたが、それは別の話です)。
ctrl-alt-delor

回答:


57

インターフェースを簡素化するためです。の代替手段はforkexecWindowsのCreateProcess関数のようなものです。パラメーターの数に注意CreateProcessしてください。それらの多くは、さらに多くのパラメーターを持つ構造体です。これは、新しいプロセスについて制御したいすべてのものをに渡す必要があるためCreateProcessです。実際、CreateProcess十分なパラメーターがないため、MicrosoftはCreateProcessAsUserCreateProcessWithLogonWを追加する必要がありました。

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

あなたは別のカレントディレクトリを使用してプロセスを開始する場合: forkchdirexec

stdin / stdout:をリダイレクトしたい場合fork、ファイルを閉じたり開いたりしますexec

ユーザーを切り替えたい場合は:forksetuidexec

これらはすべて、必要に応じて組み合わせることができます。誰かがプロセス属性の新しい種類を思い付く場合は、変更する必要はありませんforkexec

larsksが述べたように、現代のUnixのほとんどはコピーオンライトを使用forkしているため、大きなオーバーヘッドは発生しません。


16
素晴らしい説明。「UNIXを理解していない人は、UNIXを再発明したとして非難されます。」-ヘンリースペンサー
カイルジョーンズ

1
ありがとう!参照はありますか?
エレンスペルタス

1
@ Aki、nope、CreateProcess()は文字通り新しいプロセスを作成し、フォークせずにゼロから構築します。
-psusi

2
しかし、UnixのどこかにCreateProcess()に相当するものがあってはなりませんか?それ以外の場合、最初のプロセスはどのように作成されますか?神話上の創造者の神とは異なり、最初のプロセスは無からフォークすることはできません。;
スティーブン

2
@StevenMonday、はい、しかしそれはカーネルの初期化コードにあり、外部からはアクセスできません。ほとんどすべてがハードコーディングされているため、これらのパラメーターはすべて必要ありません。プロセスID 1、別名initプロセスのみを作成できます。その後、プロセスはフォークによってのみ作成されます。
cjm

5

cjmの答えに加えて、Single Unix Specificationは、という名前の関数を定義していますvfork()。この関数は、それは試してみる以外のexec familly関数を呼び出し、または呼び出しを行う場合はフォークプロセスが未定義の動作を持っていることを除いて、フォークのように動作します_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_spawnp関数)もあります。(ライブラリの呼び出しを使用してそれらを実装することも許されるforkexecし、実装例が提供されます。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.