1. ホーム
  2. c++

[解決済み] fork() は予想以上に分岐する?

2022-04-15 01:02:03

質問

次のようなコードを考えてみましょう。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    int i;
    for(i = 0; i < 2; i++)
    {
        fork();
        printf(".");
    }
    return 0;
}

このプログラムでは8個のドットを出力しています。どうしてそんなことが可能なのでしょうか?6個のドットでよいのでしょうか?

解決方法は?

その fork() プリミティブは、しばしば想像の域を出ません。 感覚をつかむまでは、それぞれの操作が何であるかを紙にトレースして、プロセスの数を考慮する必要があります。 fork() が現在のプロセスのほぼ完全なコピーを作成することを忘れないでください。 最も大きな違いは、(ほとんどの目的に対して) fork() の戻り値は親と子で異なります。 (このコードでは返り値を無視しているので、違いはありません)。

つまり、最初は1つのプロセスが存在します。 それが2つ目のプロセスを作り、両方ともドットを表示してループする。 2回目の繰り返しでは、それぞれが別のコピーを作成するので、4つのプロセスがドットを表示して終了します。 つまり、6個のドットは簡単に計算できるわけです。

しかし printf() は、その出力をバッファリングしています。 そのため、プロセスが2つしかなかったときの最初のドットは、書き込まれても表示されません。 これらのドットはバッファに残り、それはfork()で複製される。 バッファリングされたドットが現れるのは、そのプロセスが終了しようとするときである。 4つのプロセスがバッファリングされたドットを印刷し、新しいドットを追加すると、8つのドットになります。

もし、このような動作を避けたい場合は fflush(stdout); の後に printf() .