5

*nix システムでは、プロセスは fork() システム コールを使用して作成されます。たとえば、init プロセスが別のプロセスを作成するとします。最初に、init のようなコンテキストを持つプロセスを作成します。exec() を呼び出した場合にのみ、この子プロセスは新しいプロセスになります。では、なぜ中間ステップ (親と同じコンテキストで子を作成する) が必要なのでしょうか? コンテキストを作成し (時間を消費し、メモリを無駄にします)、それを上書きしているので、時間とリソースの無駄ではありませんか?

空きメモリ領域を割り当ててから exec() を呼び出すように実装されていないのはなぜですか? これにより、時間とリソースを節約できますよね?

4

4 に答える 4

4

中間ステップでは、外部プログラムに認識されることなく、子プロセスに共有リソースを設定できます。標準的な例は、パイプの構築です。

// read output of "ls"
// (error checking omitted for brevity)
int pipe_fd[2];
pipe(&pipe_fd);
if (fork() == 0) {       // child:
    close(pipe_fd[0]);   // we don't want to read from the pipe
    dup2(pipe_fd[1], 1); // redirect stdout to the write end of the pipe
    execlp("ls", "ls", (char *) NULL);
    _exit(127);          // in case exec fails
}
// parent:
close(pipe_fd[1]);
fp = fdopen(pipe_fd[0], "r");
while (!feof(fp)) {
    char line[256];
    fgets(line, sizeof line, fp);
    ...
}

forkパイプへの標準出力のリダイレクトが、との間の子でどのように行われるかに注意してくださいexec。もちろん、この単純なケースでは、適切なパラメーターが与えられれば、これを自動的に実行するスポーン APIが存在する可能性があります。しかし、このfork()設計では、子のプロセスごとのリソースを任意に操作できます。つまり、不要なファイル記述子を閉じたり、プロセスごとの制限を変更したり、権限を削除したり、シグナル マスクを操作したりできます。がなければfork()、プロセスを生成するための API は非常に太るか、あまり役に立たなくなります。実際、競合するオペレーティング システムの呼び出しを生成するプロセスは、通常、その中間に位置します。

メモリの浪費に関しては、コピー オン ライト技術で回避されます。fork()子プロセスに新しいメモリを割り当てませんが、ページが書き込まれた場合にのみページのコピーを作成するように指示して、子を親のメモリにポイントします。これによりfork()、「目次」をコピーするだけで済むため、メモリ効率が向上するだけでなく、高速になります。

于 2013-04-04T17:55:03.923 に答える
2

これは古い苦情です。多くの人がなぜfork()最初に?そして通常、彼らは新しいプロセスをゼロから作成し、その中でプログラムを実行する操作を提案します。この操作は次のように呼ばれますspawn().

そして、彼らはいつもこう言います。

実際、Unix ファミリー以外のすべてのシステム「スポーン」方式を採用しています。fork()Unix のみがandに基づいていますexec().

しかし、面白いことに、Unix は常に他のフル機能のシステムよりもはるかに高速です。それは常により多くのユーザーと負荷を処理してきました。

そして、Unix は何年にもわたってさらに高速化されてきました。Fork() はアドレス空間を実際に複製するのではなく、copy-on-writeと呼ばれる手法を使用して共有するだけです。(と呼ばれる非常に古い fork 最適化vfork()もまだ存在します。)

クールエイドを飲む。

于 2013-04-04T17:33:34.410 に答える
0

exec() を呼び出した場合にのみ、この子プロセスは新しいプロセスになります。

あまり。フォークの後、親とそれほど変わらなくても、すでに新しいプロセスがあります。exec が fork をたどる必要がない場合もあります。

では、なぜ中間ステップ (親と同じコンテキストで子を作成する) が必要なのでしょうか?

その理由の 1 つは、シバン全体を作成する効率的な方法だからです。複製は通常、最初から作成するよりも簡単です。

コンテキストを作成し (時間を消費し、メモリを浪費します)、それを上書きしているので、時間とリソースの無駄ではありませんか?

コピー オン ライト メカニズムが使用されているため、このリソースのほとんどは仮想であるため、時間とリソースの無駄にはなりません。さらに、作成されたコンテキストが上書きされると言うのは正しくありません。そもそも実際に何も書かれていないという事実を考えると、何も書き直されていません。それがCOWの要点です。プロセスのアドレス空間 (コード、ヒープ、およびスタック) のみが置き換えられ、上書きされません。環境、ファイル記述子、優先度、無視されたシグナル、現在およびルート ディレクトリ、制限、さまざまなマスク、プロセッサ バインディング、特権、およびプロセス アドレス空間とは異なる他のいくつかのものを含む、多くのプロセス コンテキストが部分的または完全に保持されます。

于 2013-04-04T22:06:59.123 に答える