cout和printf在执行fork()时的区别

4

我正在尝试使用一些测试程序来理解fork()。我发现cout和printf()之间存在不同的行为:

程序1:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
using namespace std;

int main()
{
    printf("Hi , %d\n" , getpid());
    fork();
    return 0;
}

我得到:

你好,9375

你好,9375

程序2:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
using namespace std;

int main()
{
    cout << "Hi , " <<getpid() << endl;
    fork();
    return 0;
}

我的理解是:

大家好,7277

这两个程序唯一的区别就在于第一个使用了printf()来打印输出,而第二个使用了cout

有人可以解释一下吗? 谢谢


cout = c++,printf = c。你可以在c++中同时使用它们,但建议始终使用本地语言的显示函数。 - Orel Eraki
1
第一个只有一个输出。你是写入文件而不是终端吗? - Barmar
2
可能是 Understanding of Fork in C 的重复问题。 - kuroi neko
@OrelEraki 我的问题是使用 printf 时,输出 "Hi, 9375" 会打印两次,而使用 cout 输出 "Hi, 7277" 只会打印一次。 - chenglg
1个回答

13

当你使用 stdio 时,除非它正在向终端写入内容,否则stdout是完全缓冲的;写入终端时它就是行缓冲的。

因此如果你运行一个将输出重定向到文件或管道的程序1,printf会将该行写入输出缓冲区,但不会刷新该缓冲区。当进程分叉时,缓冲区被复制到两个进程中。它们退出时,它们各自刷新其缓冲区,这样就打印出了该行内容。

如果在程序2中写入以下内容,你将得到相同的结果:

cout << "Hi , " <<getpid() << "\n";

但是,endl 除了输出换行符之外,还会刷新缓冲区。在程序1中的等效方式为:

printf("Hi , %d\n" , getpid());
fflush(stdout);

我认为你是对的,Barmar。相比之下,cout << endl 无论是否输出到终端,都会刷新缓冲区。 - Klitos Kyriacou
std::endl不仅仅是"\n",它相当于在printf之后调用fflush()。 - Joky
1
这就是我说的。如果你把 endl 改成 "\n",程序2就会像程序1一样,因为它不会刷新缓冲区。 - Barmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接