fork()打印前的语句两次[重复]

时间:2022-03-14 00:02:57

This question already has an answer here:

这个问题在这里已有答案:

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()之后,内部缓冲区被刷新,它只在你的文件中出现一次。