2

の出力の理由を誰でも説明できますか

main()   
{   
    printf("hello ");   
    fork();   
    printf("hello ");   
}

は:

ハローハローハローハロー

および出力:

main()   
{   
    printf("hello\n");   
    fork();   
    printf("hello ");   
}

は:

こんにちは
こんにちはこんにちは

\n はバッファに対してどのような違いがありますか?

4

2 に答える 2

7

forkプロセスのメモリがコピーされると。これにはstdioバッファが含まれるためhello、バッファに残っている場合は両方のプロセスによって出力されます。どちらのプロセスも処理を続行し、最終的にバッファをフラッシュすると、"hello" が 2 回表示されます。

現在、ほとんどの実装では、stdout はライン バッファリングされています。つまり、a\nがフラッシュをトリガーします。そのため、fork発生するとバッファは空になります。これを防ぐ確実な方法は、フォークする前にすべてをフラッシュすることです。

編集

では、2 番目の出力の 2 行目に hello が 2 回表示されるのはなぜですか

同じコードを実行する 2 つのプロセス (親と子) があるため、printf2 回実行されます。

于 2012-08-15T04:17:39.093 に答える
2

cnicutar の回答では、一般的な実装で起こっていることの背後にあるメカニズムについて説明していますが、中心的な問題は、プログラムが未定義の動作を呼び出していることです。POSIX では、開いているファイルの「アクティブ ハンドル」の切り替えに関する規則が定められています。

http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01

forkは、ファイルの新しいハンドルが存在する状況の 1 つであり、 の前にアクティブなハンドルを切り替える準備をしていない限り、forkの後に両方を使用することは未定義の動作forkです。

fork() の後、前に 1 つ存在した場所に 2 つのハンドルが存在することに注意してください。アプリケーションは、両方のハンドルにアクセスできる場合、両方とも、もう一方が最初にアクティブなハンドルになる可能性がある状態にあることを確認する必要があります。アプリケーションは、アクティブなハンドルの変更の場合とまったく同じように fork() を準備する必要があります。(プロセスの 1 つによって実行される唯一のアクションが exec 関数の 1 つまたは _exit() (exit() ではない) である場合、そのプロセスでハンドルにアクセスすることはありません。)

于 2012-08-15T04:41:32.727 に答える