fork() での予期せぬ分岐の奇妙なケース
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() は現在のプロセスのレプリカを作成し、親プロセスと子プロセスを作成します。
最初は 1 つのプロセスがあり、それが 2 つに分岐します。これらのプロセスは両方とも、for ループを段階的に実行し、毎回ドットを出力します。 2 回目の反復では、各プロセスが再びフォークし、合計 4 つのプロセスが作成されます。これら 4 つのプロセスは、終了する前にドットを出力します。
バッファリングされた出力と遅延された外観
ただし、printf() は出力をバッファリングします。つまり、出力を送信する前に複数の出力を蓄積します。すぐに。 4 つのプロセスすべてが 2 番目のドットを印刷すると、バッファリングされます。ここで卑劣な効果が発生します。
fork() の際、バッファリングされたドットは子プロセスに継承されます。したがって、各子プロセスが終了すると、そのバッファリングされたドットが出力ストリームに表示されます。これら 4 つの遅延ドットを段階的に印刷される 4 つのドットに追加すると、予想外の合計 8 つになります。
バッファリングされたドットの回避
このバッファリングされた動作をバイパスするには、以下を呼び出すことをお勧めします。 fflush(標準出力);各 printf() ステートメントの後。これにより、出力が直ちに送信され、予想される数のドットが表示されるようになります。
以上が単純な fork() ループで 2 つではなく 8 つのドットが生成されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。