endl和\ n的不同行为与fork()

时间:2017-03-10 15:48:49

标签: c++ fork

我有一个c ++程序,可以创建五个子进程。

#include<iostream>
#include<unistd.h>
#include<sys/types.h>
using namespace std;

int main()
{
    pid_t pid;
    pid=fork();
    if(pid==0)
    {
        cout<<"Child Process 1"<<endl;
    }

    pid=fork();
    if(pid==0)
    {
        cout<<"Child Process 2"<<endl;
    }

     if(pid==0)
    {
        pid=fork();
        if(pid==0)
        {
            cout<<"child process 3"<<endl;
        }
    }

    return 0;
}

上述程序的输出是:

Child Process 1
Child Process 2
Child Process 2
child process 3
child process 3

但问题是当我使用\ n而不是endl时输出是不同的

#include<iostream>
#include<unistd.h>
#include<sys/types.h>
using namespace std;

int main()
{
    pid_t pid;
    pid=fork();
    if(pid==0)
    {
        cout<<"Child Process 1\n";
    }

    pid=fork();
    if(pid==0)
    {
        cout<<"Child Process 2\n";
    }

     if(pid==0)
    {
        pid=fork();
        if(pid==0)
        {
            cout<<"child process 3\n";
        }
    }

    return 0;
}

使用\ n的上述程序的输出是:

Child Process 1
Child Process 2
Child Process 1
Child Process 2
Child Process 2
child process 3
Child Process 1
Child Process 2
child process 3

为什么在同一个程序中endl和\ n的输出不同?

2 个答案:

答案 0 :(得分:3)

大多数操作系统缓冲标准输出作为优化。

endl以及编写换行符,同时刷新缓冲区,这实际上意味着任何排队的标准输出都会立即写入控制台。

\n不会刷新缓冲区。

因此,您在输出方面的差异是由于与您的并发模型进行交互。

答案 1 :(得分:2)

std::cout通常不会立即打印文本,而是将其保存在缓冲区中。当进程分叉时,该内部缓冲区将与进程中的其他所有内容一起复制;父母和孩子最终得到相同的缓冲区。

在您的示例中显然发生的事情是缓冲区仅在fork之后刷新并打印到屏幕上,可能就在进程结束之前。

使用std::endl,然后立即刷新 作为副作用,因此在子进程可以获得副本之前,父进程将打印内容。