让子进程 printf 正确重定向 stdout
Having child processes printf to redirected stdout correctly
我正在使用 freopen()
重定向 stdout
一个进程,只要它只是一个进程,一切都很好。
但是,如果我这样做:
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++;
}
最初打印的行一遍又一遍地重新打印在文件上。我应该做些什么来避免这种情况发生?
The first printed lines are re-printed on the file over and over.
这是因为标准 C 库在使用 stdio
函数时将 缓冲 应用于标准输出流。特别是,当 stdout
被重定向到一个文件时,缓冲模式从 line-buffered 变为完全缓冲(具有由库定义的大小的缓冲区)。在 line-buffered 模式下,仅当遇到换行符时才刷新缓冲区(以及实际写入的数据), 但是 在完全缓冲模式下,这仅在最大缓冲区大小为达到。
当您创建多个进程时,它们都共享 parent 的同一个缓冲区。由于在生成新 children 之前您没有到达缓冲区的末尾,并且您没有清空它,因此它们都将具有相同的缓冲区内容。之后,当每个 children 死亡时,缓冲区将被标准库自动刷新。
Is there anything particular I should do to avoid this from happening?
是的。在创建 children.
之前刷新缓冲区
freopen("stdout.txt", "a+", stdout);
printf("Initial line.\n");
fflush(stdout);
// ...
您可能还想 exit()
在 child 完成其工作后的下一个周期之前:
int i=0;
while(i<1000)
{
if(fork()) {
wait(NULL);
} else {
printf("Line %d.\n", i);
exit(0);
}
i++;
}
我正在使用 freopen()
重定向 stdout
一个进程,只要它只是一个进程,一切都很好。
但是,如果我这样做:
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++;
}
最初打印的行一遍又一遍地重新打印在文件上。我应该做些什么来避免这种情况发生?
The first printed lines are re-printed on the file over and over.
这是因为标准 C 库在使用 stdio
函数时将 缓冲 应用于标准输出流。特别是,当 stdout
被重定向到一个文件时,缓冲模式从 line-buffered 变为完全缓冲(具有由库定义的大小的缓冲区)。在 line-buffered 模式下,仅当遇到换行符时才刷新缓冲区(以及实际写入的数据), 但是 在完全缓冲模式下,这仅在最大缓冲区大小为达到。
当您创建多个进程时,它们都共享 parent 的同一个缓冲区。由于在生成新 children 之前您没有到达缓冲区的末尾,并且您没有清空它,因此它们都将具有相同的缓冲区内容。之后,当每个 children 死亡时,缓冲区将被标准库自动刷新。
Is there anything particular I should do to avoid this from happening?
是的。在创建 children.
之前刷新缓冲区freopen("stdout.txt", "a+", stdout);
printf("Initial line.\n");
fflush(stdout);
// ...
您可能还想 exit()
在 child 完成其工作后的下一个周期之前:
int i=0;
while(i<1000)
{
if(fork()) {
wait(NULL);
} else {
printf("Line %d.\n", i);
exit(0);
}
i++;
}