4

以下のコードスニペットについて考えてみます。

int main()
{
    fork();
    fork();
    fork();
    printf("Hello World\n");
}

出力を取得しています:[ubuntu12.04]

aashish@aashish-laptop:~$ ./a.out
Hello World
Hello World
Hello World
aashish@aashish-laptop:~$ Hello World <---------------------------
Hello World
Hello World
Hello World
Hello World

プロセス実行終了後に「HelloWord」が出力されるのはなぜですか?

4

4 に答える 4

5

簡単に言うと、相互に非同期で実行される複数のプロセスを作成しているということです。長い答えは次のとおりです。

シェルプロンプトで./a.outと入力すると、プログラムを実行するプロセスが作成されます。そのプロセスを1と呼びましょう。

プロセス1はfork()を呼び出します。これにより、新しい子プロセスであるプロセス2が作成され、最初のfork()呼び出しの後、1と2の両方が実行を継続し、2番目のfork()呼び出しに進みます。プロセス1は子プロセス3を作成し、プロセス2は子プロセス4を作成します。4つのプロセスはすべて、2番目のfork()の後から続き、最後のfork()呼び出しに進みます。プロセス1はプロセス5を作成します。プロセス2はプロセス6を作成します。プロセス3はプロセス7を作成します。プロセス4はプロセス8を作成します。

非アーティストによるプロセス階層のレンダリング

これらのプロセス番号は任意であることに注意してください。この順序で作成される保証はありません。

非同期は、最初のfork()が実行されるとすぐに機能します。システムは、子に関して親をスケジュールすることについての保証を提供しません。理論的には、子は親が続行する前に完了するまで実行でき、親は子がリソースを取得する前に終了する可能性があります。最も可能性の高いシナリオは、中間のどこかにあります。元のプロセスはその子孫とリソースを共有するため、すべてが同時に実行されます。

パズルの最後のピースは、シェルがプロセス1の完了を待機しているという事実から生じます。プロセス1のみ。シェルは、プロセス1が他のプロセスを開始したことを認識(または処理)しません。したがって、プロセス1が完了すると、シェルはプロンプトを表示します。たまたま、プロセス1の子孫の一部はまだprintf()ステートメントに到達していませんでした。彼らがそこに着くまでに、シェルはすでにプロンプ​​トを表示していました。

これをさらに詳しく調べるには、fork()呼び出しをprintf( "%d \ n"、fork());に変更してみてください。および/またはprintf( "Hello World \ n")printf( "Hello from pid%d \ n"、getpid())に変更します。

于 2012-08-03T21:39:40.903 に答える
3

2番目のシェルプロンプトの後に表示される「HelloWorld」出力は、シェル(ユーザー)によって起動されたプロセスからではなく、フォークされたプロセスから取得されます。

于 2012-08-03T19:29:17.773 に答える
0

これは、1つのフォーク(2)を作成してから、もう一度(4)フォークし、次に(8)フォークごとに、Helloworldを印刷するためです。そのため、8つの出力が得られました。

于 2012-08-03T19:31:21.950 に答える
0
int main() {
    pid_t c[3];
    int i, n = 0;
    for (i = 0; i < 3; ++i) {
        switch ((c[n] = fork())) {
        case 0:  break;
        case -1: perror("fork"); exit(EXIT_FAILURE);
        default: ++n;
        }
    }
    printf("[%d] Hello World\n", (int)getpid());
    // Without waiting, some children may still be running when the
    // parent exits. This makes it look like output is generated
    // after the process is over, when in fact not all the processes
    // are done yet.
    //
    // The process is not really finished until its children are
    // finished. The wait call waits on a child process to finish.
    for (i = 0; i < n; ++i) wait(0);
    return 0;
}
于 2012-08-03T19:43:04.180 に答える