Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ fork()和输出_C++_Linux_Unix_Fork - Fatal编程技术网

C++ fork()和输出

C++ fork()和输出,c++,linux,unix,fork,C++,Linux,Unix,Fork,我有一个简单的程序: int main() { std::cout << " Hello World"; fork(); } intmain() { std::cout如果您使用: std::cout << " Hello World" << std::flush; std::cout字符串不会立即写入屏幕,而是写入内部缓冲区。子进程继承输出缓冲区的副本,因此当子进程的cout自动刷新时,Hello World会打印到屏幕上。父进程也会打印

我有一个简单的程序:

int main()
{
    std::cout << " Hello World";
    fork();
}
intmain()
{
std::cout如果您使用:

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

std::cout字符串不会立即写入屏幕,而是写入内部缓冲区。子进程继承输出缓冲区的副本,因此当子进程的
cout
自动刷新时,
Hello World
会打印到屏幕上。父进程也会打印
Hello World


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

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

如果将程序更改为:

std::cout << " Hello World;" << std::endl;
std::cout因为调用fork()时没有首先刷新所有缓冲区

cout.flush();
fork();

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


发生这种情况的唯一原因是cout是缓冲IO。
。如果使用未缓冲的cerr,您应该只会看到一次消息,pre fork。

您可能在这里看到的是缓冲的效果。通常,输出会被缓冲,直到显式刷新或隐式完成,例如输出新行。由于输出是缓冲的,分叉进程的两个副本都有缓冲的输出,因此在进程终止并刷新缓冲区时都会显示输出。要输出的代码只执行一次。问题是输出缓冲区没有刷新。因此,分叉进程时,
“Hello World”
仍在输出缓冲区中。当两个程序退出时,它们的输出缓冲区将被刷新,您将看到两次输出


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

原因是当您调用
std::coutt时,这就是fork的作用,它使用父进程的内存生成进程。确实有很多
fork()
最近的问题…嗯…嗯…子进程在调用fork之后开始执行程序的代码。因此子进程无法执行fork之上的代码。我不认为是访问。我认为是操作系统类。请参阅最新的refactormycode.com:我不会说分析完全正确。子进程不是“在幕后重新运行”。@MichaelMior:你说得对。我错过了“重新运行”部分。我编辑了语言。这只是因为cout是用户空间缓冲IO^_^