ホームページ >バックエンド開発 >C++ >`fork()` ループが予想以上の出力を生成するのはなぜですか?

`fork()` ループが予想以上の出力を生成するのはなぜですか?

DDD
DDDオリジナル
2024-11-04 07:46:31252ブラウズ

Why Does My `fork()` Loop Produce More Output than Expected?

なぜ fork() は予想以上に分岐するのでしょうか?

次のコード スニペットを考えてみましょう:

<code class="c">#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;
}</code>

実行すると、このプログラムは驚くべき出力を行います。予想される 6 ではなく 8 つのドットです。これはどのように可能ですか?

fork() の動作

予期しない出力を理解するには、fork() プリミティブの複雑さを詳しく調べる必要があります。 fork() が呼び出されると、現在のプロセスのほぼ完全なコピーが作成されます。 (ほとんどの目的において) 最も注目すべき違いは、親プロセスと子プロセスの戻り値が異なることです。ただし、提供されるコードはこれらの戻り値を無視するため、この区別は実質的に無関係になります。

実行のトレース

最初は、単一のプロセスが存在します。続いて 2 番目のプロセスが作成され、2 つのプロセスがドットを印刷してループを継続することになります。 2 回目の反復では、各プロセスが再びコピーを作成し、ドットを出力して終了する 4 つのプロセスにつながります。これは最初の 6 つの点の説明です。

バッファリングと遅延出力

ただし、printf() は出力バッファリングを使用します。したがって、2 つのプロセスによって印刷された最初のドットはすぐには見えません。これらのドットはバッファリングされたままになり、fork() 中に複製されます。バッファリングされたドットがフラッシュされて表示されるのは、プロセスが終了したときのみです。したがって、バッファリングされたドットを出力する 4 つのプロセスと 1 つの新しいドットにより、予期しない 8 ドットの出力が生成されます。

予期しない出力の防止

この動作を抑制するには、fflush(stdout);各 printf() ステートメントの後に呼び出すことができるため、ドットがすぐに表示されます。

以上が`fork()` ループが予想以上の出力を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。