私はfork/vfork関数で少し遊んでいますが、私には困惑することがあります。スティーブンスの本には次のように書かれています。
図8.3では、exitではなく_exitを呼び出していることに注意してください。
セクション7.3で説明したように、_exitは標準のI/Oバッファのフラッシュを実行しません。代わりにexitを呼び出すと、結果は不確定になります。標準のI/Oライブラリの実装によっては、出力に違いが見られない場合や、親のprintfからの出力が消えている場合があります。子がexitを呼び出すと、実装は標準のI/Oストリームをフラッシュします。これがライブラリによって実行される唯一のアクションである場合、子が_exitを呼び出した場合に生成される出力との違いはわかりません。ただし、実装が標準I / Oストリームも閉じる場合、標準出力のFILEオブジェクトを表すメモリはクリアされます。子は親のアドレス空間を借用しているため、親が再開してprintfを呼び出すと、出力は表示されず、printfは-1を返します。子は親のファイル記述子配列のコピーを取得するため、親のSTDOUT_FILENOは引き続き有効であることに注意してください(図8.2に戻るを参照)。最新のexitの実装のほとんどは、ストリームを閉じるのに苦労することはありません。プロセスが終了しようとしているため、カーネルはプロセスで開いているすべてのファイル記述子を閉じます。ライブラリでそれらを閉じると、何のメリットもなくオーバーヘッドが追加されます。
そこで、printfエラーが発生するかどうかをテストしようとしましたが、vforkのマニュアルには次のようなものがあります。
開いているすべてのstdio(3)ストリームがフラッシュされ、閉じられます。tmpfile(3)によって作成されたファイルは削除されます。
しかし、このプログラムをコンパイルして実行すると、次のようになります。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
int s;
pid_t ret;
if (vfork() == 0)
{
//abort();
exit(6);
}
else
{
ret=wait(&s);
printf("termination status to %d\n",s);
if (WIFEXITED(s))
printf("normalnie, status to %d\n",WEXITSTATUS(s));
}
return 0;
}
すべてが正常に機能しています。printfエラーは発生しません。何故ですか?