188

次のコードを検討してください。

#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つのドットがあるべきではありませんか?

4

3 に答える 3

247

プリミティブはfork()しばしば想像力を伸ばします。それを感じるまで、各操作が何であるかを紙で追跡し、プロセスの数を説明する必要があります。fork()が現在のプロセスのほぼ完全なコピーを作成することを忘れないでください。(ほとんどの目的で)最も重要な違いは、fork()の戻り値が親と子で異なることです。(このコードは戻り値を無視するため、違いはありません。)

したがって、最初は1つのプロセスがあります。これにより、2番目のプロセスが作成され、どちらもドットとループを出力します。2回目の反復では、それぞれが別のコピーを作成するため、4つのプロセスでドットを印刷して終了します。したがって、ご想像のとおり、6つのドットを簡単に説明できます。

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

その動作を避けたい場合は、fflush(stdout);後に呼び出してくださいprintf()

于 2012-06-21T06:58:19.537 に答える
70

出力ストリームにコミットされていないバッファがあります。stdoutはラインバッファリングされ、バッファは残りのプロセスと一緒に複製されます。プログラムが終了すると、コミットされていないバッファが2回書き込まれます(プロセスごとに1回)。両方を使用して

printf("a\n");

printf("a "); fflush(stdout);

問題を示さないでください。

最初の例では、出力ストリームバッファにそれぞれ2つのドットがある4つのプロセスを作成します。各ストリームが終了すると、バッファがフラッシュされ、8つのドットが生成されます。

于 2012-06-21T06:59:15.913 に答える
2

i=0のとき

Process_1: バッファリングされたテキスト = 1 ドット

Process_2 (Process_1 で作成): バッファリングされたテキスト = 1 ドット

i=1のとき

Process_3 (Process_1 によって作成): Process_1 から 1 つのバッファーされたドットを継承し、1 つのドットを単独で印刷します。合計で、Process_3 は 2 つのドットを印刷します。

Process_4 (Process_2 によって作成): Process_2 から 1 つのバッファーされたドットを継承し、1 つのドットを単独で印刷します。合計で、Process_4 は 2 つのドットを印刷します。

Process_1 : 2 つのドットを印刷します (i=0 の場合は 1 つのバッファード ドット、i=1 の場合は別のドット)。

Process_2 : 2 つのドットを印刷します (i=0 の場合は 1 つのバッファード ドット、i=1 の場合は別のドット)。

最終出力: 8 ドット。:)

于 2013-12-24T20:12:18.487 に答える