fork() 和输出

发布于 2025-01-07 21:57:52 字数 258 浏览 1 评论 0原文

我有一个简单的程序:

int main()
{
    std::cout << " Hello World";
    fork();
}

程序执行后我的输出是:Hello World Hello World。为什么会发生这种情况而不是一个 Hello world?我猜测子进程在幕后重新运行,并且输出缓冲区在进程之间共享或类似的事情,但情况是这样还是发生了其他事情?

I have a simple program:

int main()
{
    std::cout << " Hello World";
    fork();
}

After the program executes my output is: Hello World Hello World. Why does this happen instead of a single Hello world? I'm guessing that the child process is rerun behind the scenes and the output buffer is shared between the processes or something along those lines, but is that the case or is something else happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

忆伤 2025-01-14 21:57:52

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

这种情况发生只是因为 cout 是缓冲 IO。如果您使用未缓冲的 cerr,则在分叉前,您应该只能看到该消息一次。

This isn't quite what you thought originally. The output buffer is not shared - when you execute the fork, both processes get a copy of the same buffer. So, after you fork, both processes eventually flush the buffer and print the contents to screen separately.

This only happens because cout is buffered IO. If you used cerr, which is not buffered, you should only see the message one time, pre-fork.

幸福不弃 2025-01-14 21:57:52

标准输出使用缓冲 IO。当调用 fork() 时,标准输出不会刷新,并且缓冲的内容会在子进程中复制。当进程退出时,这些缓冲区将被刷新,从而产生您看到的两个输出。

如果您将程序更改为:

std::cout << " Hello World;" << std::endl;

您应该只看到一个。

standard output uses buffered IO. When the fork() is called the standard output is not flushed and the buffered content is replicated in the child process. These buffers are flushed when the process exit, resulting in the two outputs that you see.

If you change the program to:

std::cout << " Hello World;" << std::endl;

you should see only one.

香草可樂 2025-01-14 21:57:52

因为您调用 fork() 时没有先刷新所有缓冲区。

cout.flush();
fork();

Because you called fork() without flushing all buffers first.

cout.flush();
fork();
压抑⊿情绪 2025-01-14 21:57:52

输出“Hello World”的代码仅执行一次。问题是输出缓冲区未刷新。因此,当您分叉该进程时,“Hello World”仍然位于输出缓冲区中。当两个程序退出时,它们的输出缓冲区将被刷新,您将看到两次输出。

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

The code to output "Hello World" is only executed once. The issue is that the output buffer isn't flushed. So when you fork the process, "Hello World" is still sitting in the output buffer. When both programs exit, their output buffers will be flushed and you'll see the output twice.

The easiest way to demonstrate this is by adding a newline at the end of your string, which will cause an implicit flush, or explicitly flush with std::cout.flush();. Then you'll only see the output once.

佞臣 2025-01-14 21:57:52

如果您使用:

std::cout << " Hello World" << std::flush;

您只会看到一个。我猜 fork() 会复制 std::cout 写入的任何输出缓冲区。

If you use:

std::cout << " Hello World" << std::flush;

You only see one. I guess fork() copies whatever output buffer std::cout writes to.

も星光 2025-01-14 21:57:52

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

如果在 fork() 之前刷新 cout,问题几乎肯定会消失。

The string is not immediately written to the screen; instead, it's written to an internal buffer. The child process inherits a copy of the output buffer, so when the child's cout is automatically flushed, Hello World is printed to the screen. The parent also prints Hello World.

If you flush cout before the fork(), the problem will almost certainly go away.

三生路 2025-01-14 21:57:52

原因是,当您调用 std::cout<< 时,它本身并不真正执行输出,而是将数据保留在系统的缓冲区中。当您进行分叉时,代码和数据以及所有关联的缓冲区都会被复制。最后,父亲和儿子都将它们刷新到标准输出,因此您会看到输出重复。

The reason is that the when you invoke std::cout<< it doesn't really perform the output itself but data is left in a buffer in the system. When you do the fork, both code and data are copied, as well as all the buffers associated. Finally, both father and son flush them to the standard output and thus you see the output duplicated.

怂人 2025-01-14 21:57:52

您可能在这里看到的是缓冲效果。一般来说,输出会被缓冲,直到它被显式刷新或通过输出新行等操作隐式完成。由于输出被缓冲,分叉进程的两个副本都具有缓冲输出,因此都在进程终止并刷新缓冲区时显示它

What you're likely seeing here is an effect of buffering. In general output is buffered until it's explicitly flushed or implicitly done with an action like outputting a new line. Because the output is buffered both copies of the forked process have bufferred output and hence both display it upon the process terminating and flushing the buffer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文