6

私はfork()がより高いレベルで何をするかを知っています。私が知りたいのはこれです-

  1. フォーク呼び出しがあるとすぐに、トラップ命令が続き、制御がジャンプしてフォーク「ハンドラー」を実行します。さて、別のアドレス空間とプロセス制御ブロックを作成して親プロセスを複製することにより、子プロセスを作成するこのハンドラーは、各プロセスに1つずつ、2つの値をどのように返しますか?

  2. 実行のどの時点で、フォークは2つの値を返しますか?

簡単に言えば、フォークコールの後に下位レベルで発生するステップバイステップのイベントを誰かが説明できますか?

4

2 に答える 2

1

それほど難しいことではありません。fork()システムコールのカーネルの半分は、前述のようにプロセス制御ブロックを介して2つのプロセスの違いを認識できますが、それを行う必要はありません。したがって、擬似コードは次のようになります。

int fork()
{
    int orig_pid = getpid();

    int new_pid = kernel_do_fork();     // Now there's two processes

    // Remember, orig_pid is the same in both procs
    if (orig_pid == getpid()) {
        return new_pid;
    }

    // Must be the child
    return 0;
}

編集: ナイーブバージョンは、説明どおりに機能します。新しいプロセスコンテキストを作成し、関連するすべてのスレッドコンテキストをコピーし、すべてのページとファイルマッピングをコピーし、新しいプロセスを「実行準備完了」リストに追加します。

あなたが混乱しているのは、これらのプロセスが再開するとき(つまり、親がkernel_do_forkから戻り、子が初めてスケジュールされるとき)、関数の途中で開始する(つまり、最初に実行する)ことだと思います。 'もしも')。これは正確なコピーです。両方のプロセスが関数の後半を実行します。

于 2010-02-05T05:36:50.723 に答える
1

各プロセスに返される値は異なります。親/元のスレッドは子プロセスのPIDを取得し、子プロセスは0を取得します。

Linuxカーネルは、親プロセスの現在のスレッドをコピーするときにeaxレジスタの値を変更することにより、x86でこれを実現します。

于 2010-02-05T05:40:23.447 に答える