fork()和输出

Eum*_*coz 56 c++ unix linux fork

我有一个简单的程序:

int main()
{
    std::cout << " Hello World";
    fork();
}
Run Code Online (Sandbox Code Playgroud)

程序执行后我的输出是:Hello World Hello World.为什么会发生这种情况而不是单一Hello world?我猜测子进程是在幕后重新运行的,输出缓冲区是在进程之间共享的,还是那些沿着这些进程共享的东西,但就是这种情况还是其他事情发生了?

Joh*_*0te 93

这不是你最初的想法.输出缓冲区不是共享的 - 当您执行fork时,两个进程都会获得相同缓冲区的副本.因此,在fork之后,两个进程最终刷新缓冲区并将内容分别打印到屏幕.

不仅是因为Cout的缓冲IO.如果你使用了cerr,它不是缓冲的,你应该只看到一次消息,pre-fork.

  • 这只是因为cout是用户空间缓冲的IO.^ _ ^ (6认同)

hmj*_*mjd 44

标准输出使用缓冲IO.当fork()被称为标准输出不是冲洗和缓冲的内容在子进程中复制.进程退出时会刷新这些缓冲区,从而产生您看到的两个输出.

如果您将程序更改为:

std::cout << " Hello World;" << std::endl;
Run Code Online (Sandbox Code Playgroud)

你应该只看到一个.

  • 这个答案澄清了我的一切.非常感谢两次 (2认同)

Jos*_*hua 17

因为您先调用fork()而不先刷新所有缓冲区.

cout.flush();
fork();
Run Code Online (Sandbox Code Playgroud)


Mic*_*ior 10

输出的代码"Hello World"只执行一次.问题是输出缓冲区没有刷新.所以当你分叉进程时,"Hello World"仍然会坐在输出缓冲区中.当两个程序都退出时,它们的输出缓冲区将被刷新,你将看到输出两次.

证明这一点的最简单方法是在字符串末尾添加换行符,这将导致隐式刷新,或显式刷新std::cout.flush();.然后你只会看到输出一次.


Jam*_*lin 9

如果您使用:

std::cout << " Hello World" << std::flush;
Run Code Online (Sandbox Code Playgroud)

你只看到一个.我想fork()复制输出缓冲区std::cout写入的内容.


NPE*_*NPE 6

字符串不会立即写入屏幕; 相反,它被写入内部缓冲区.子进程继承了输出缓冲区的副本,因此当子进程cout自动刷新时,Hello World会打印到屏幕上.父母也打印Hello World.

如果你cout在之前冲洗fork(),问题几乎肯定会消失.