フォークコールと再帰

フォークコールと再帰
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    fork();
    fork();
    fork();

    puts("hi");

    return 0;
}

プログラムは「hi」を8回印刷して終了します。なぜ?すべての再帰fork呼び出しはmain次のとおりですf(): "hi"; f()

答え1

いいえ、fork「再帰」という伝統的な意味の再帰ではありません。呼び出しはfork()現在のプロセスをコピーするので、「2回返されます」。子プロセスの場合は戻り値は 0 で、親プロセスの場合は戻り値は子 PID です。 fork()するいいえ再起動 - これは次のものとmain似ています。forkexec

これがあなたのプログラムがどのように機能するかです。まず行番号を挿入してみましょう。

 1: #include <stdio.h>
 2: #include <stdlib.h>
 3: #include <string.h>
 4:
 5: int main(int argc, char *argv[])
 6: {
 7:    fork();
 8:    fork();
 9:    fork();
10:
11:    puts("hi");
12:
13:    return 0;
14: }

プログラムを起動し、そのPIDが次のようになるとします。

  • 7行目以降の呼び出しは、fork2つの別々のプロセスを生成します。全8号線で、PIDが付いている1つ(オリジナル)とpidC1(新しい子供)。

  • 8行を実行し、PIDを使用して新しい子プロセスを作成します。C2。両方そしてC2今9号線にあります。同時に、C18行を実行して新しいサブプロセスを作成します。CC1。両方CC1そしてC19号線にもあります。 (完全に関連付けられていませんが、上記の2つの文が表示される順序は定義されていません。マルチプロセッサシステムでは同時に表示されることがあります。)

今4つのプロセスがあります。C1C2CC1。ご覧のとおり、プロセスfork数が連続して2倍になります。 3つの呼び出しがあるため、最終的に2、3、またはfork8つのプロセスが作成されます。家系図は次のとおりです。

P (initial process, started by you)
+-- C1 (created on line 7)
|   +-- CC1 (created on line 8)
|   |   +-- CCC1 (created on line 9)
|   +-- CC2 (created on line 9)
+-- C2 (created on line 8)
|   +-- CC3 (created on line 9)
+-- C3 (created on line 9)

各プロセスはツリーの親プロセスによって生成されます。

答え2

                           main()
                             |
                             |
                      fork()  ------------------
                              |                 |
                     fork()   -------        -------
                              |     |        |      |
                   fork()   ----   ----     ---    ---
                            |  |   |   |    |  |   |  |

これは上記のコードのプロセスツリーであり、これがfork()がどのように機能するかです。そして、8が印刷される理由は、常に2のn平方であることを意味します(ここで、nは呼び出し回数、つまりfork()です)。

関連情報