问题描述
我正在使用stdout
重定向一个进程上的freopen()
,只要它是一个进程,就可以了。
但是,如果我做这样的事情:
freopen("stdout.txt","a+",stdout);
printf("Initial line.\n");
int i=0;
while(i<1000)
{
if(fork())
wait(NULL);
else
printf("Line %d.\n",i);
i++;
}
最初打印的行会一遍又一遍地重新打印在文件上。我有什么特别的措施可以避免这种情况的发生?
解决方法
一遍又一遍地将第一行打印的行重新打印在文件上。
这是因为在使用stdio
函数时,标准C库将 buffering 应用于标准输出流。特别是,当stdout
重定向到文件时,缓冲模式将从行缓冲更改为完全缓冲(使用库定义的大小的缓冲区)。在行缓冲模式下,仅当遇到换行符时才刷新缓冲区(并实际写入数据),但 在完全缓冲模式下仅在达到最大缓冲区大小时才会发生。
当您创建多个进程时,它们都共享父进程的相同缓冲区。由于在生成新的子代之前您没有到达缓冲区的末尾,并且您不清空它,因此它们将具有相同的缓冲区内容。之后,当每个子进程都死亡时,标准库将自动刷新缓冲区。
我应该采取什么特别措施来避免这种情况的发生?
是的。在创建子代之前先冲洗缓冲区。
freopen("stdout.txt","a+",stdout);
printf("Initial line.\n");
fflush(stdout);
// ...
您还可能想在孩子完成工作后的下一个周期之前exit()
:
int i=0;
while(i<1000)
{
if(fork()) {
wait(NULL);
} else {
printf("Line %d.\n",i);
exit(0);
}
i++;
}