This question already has an answer here:
这个问题在这里已有答案:
- printf anomaly after “fork()” 3 answers
- printf异常后“fork()”3回答
I was experimenting with fork()
and re-direction to check whether the re-directions done in the parent apply to the child too. I wrote the following simple program
我正在尝试使用fork()并重新定向以检查父项中的重定向是否也适用于孩子。我写了以下简单的程序
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main ()
{
freopen( "error.txt", "w+t", stdout ); // From now on, stdout = error.txt
printf (" ERROR! WHY DONT U UNDERSTAND?\n");
if ( fork() == 0 )
{
printf(" I AM CHILD\n");
exit(0);
}
else-
{
printf (" EITHER I AM A PARENT OR SOMETHING GOT SCREWED\n");
}
return 0;
}
The output ( error.txt
) I got is
我得到的输出(error.txt)是
ERROR! WHY DONT U UNDERSTAND?
EITHER I AM A PARENT OR SOMETHING GOT SCREWED
ERROR! WHY DONT U UNDERSTAND?
I AM CHILD
Surprisingly, ERROR! WHY DONT U UNDERSTAND?
is printing twice even though it appears much before the fork()
is called and should only be printed once by the parent.
令人惊讶的是,错误!为什么你不理解?即使它在调用fork()之前出现很多并且只应由父级打印一次,也会打印两次。
Can anyone shed some light on this?
任何人都可以对此有所了解吗?
4 个解决方案
#1
10
Since after reopen
the stream is non-interactive, it's fully buffered and doesn't flush on '\n'
. Before fork
is called the buffer still contains the message, and after fork
this buffered message was duplicated (because both processes got their own copies of stdout
) and then flushed by both the parent and the child. See part 7.19.3 of C standard.
由于重新打开后,流是非交互式的,因此它是完全缓冲的,并且不会在'\ n'上刷新。在调用fork之前,缓冲区仍然包含消息,并且在fork之后,这个缓冲的消息被复制(因为两个进程都有自己的stdout副本)然后由父节点和子节点刷新。参见C标准的7.19.3部分。
You can avoid such behavior by calling fflush
just before fork
.
你可以通过在fork之前调用fflush来避免这种行为。
#2
3
It's because of buffering. Do a fflush
right after printf
.
这是因为缓冲。在printf之后立即进行fflush。
Both processes end up with the same copy of stdio
's internal stuff and both proceed to flush it at exit
. You might also prevent it from happening if you call _exit
in the child.
这两个进程最终都得到了stdio内部东西的相同副本,并且都在退出时继续刷新它。如果在孩子中调用_exit,也可以防止它发生。
#3
1
flushing the buffer will solve the problem. use fflush just after the print statement.
刷新缓冲区将解决问题。在print语句之后使用fflush。
#4
0
It seems that the ERROR! WHY DONT U UNDERSTAND
is still buffered after forking and gets written by both processes.
好像错了!为什么不理解仍然在分叉后缓冲并由两个过程写入。
If you add
如果你添加
fflush(stdout);
right after your first printf()
the internal buffer is flushed and it only appears once in your file.
在你的第一个printf()之后,内部缓冲区被刷新,它只在你的文件中出现一次。
#1
10
Since after reopen
the stream is non-interactive, it's fully buffered and doesn't flush on '\n'
. Before fork
is called the buffer still contains the message, and after fork
this buffered message was duplicated (because both processes got their own copies of stdout
) and then flushed by both the parent and the child. See part 7.19.3 of C standard.
由于重新打开后,流是非交互式的,因此它是完全缓冲的,并且不会在'\ n'上刷新。在调用fork之前,缓冲区仍然包含消息,并且在fork之后,这个缓冲的消息被复制(因为两个进程都有自己的stdout副本)然后由父节点和子节点刷新。参见C标准的7.19.3部分。
You can avoid such behavior by calling fflush
just before fork
.
你可以通过在fork之前调用fflush来避免这种行为。
#2
3
It's because of buffering. Do a fflush
right after printf
.
这是因为缓冲。在printf之后立即进行fflush。
Both processes end up with the same copy of stdio
's internal stuff and both proceed to flush it at exit
. You might also prevent it from happening if you call _exit
in the child.
这两个进程最终都得到了stdio内部东西的相同副本,并且都在退出时继续刷新它。如果在孩子中调用_exit,也可以防止它发生。
#3
1
flushing the buffer will solve the problem. use fflush just after the print statement.
刷新缓冲区将解决问题。在print语句之后使用fflush。
#4
0
It seems that the ERROR! WHY DONT U UNDERSTAND
is still buffered after forking and gets written by both processes.
好像错了!为什么不理解仍然在分叉后缓冲并由两个过程写入。
If you add
如果你添加
fflush(stdout);
right after your first printf()
the internal buffer is flushed and it only appears once in your file.
在你的第一个printf()之后,内部缓冲区被刷新,它只在你的文件中出现一次。