为什么程序打印4次“do”而不是只打印一次“do”?
代码:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf(" do ");
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");
else printf("\n");
}程序打印do ma to do to
发布于 2017-05-09 22:39:30
在"if“语句中调用fork两次:
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");在第一个fork上,父A产生一个子B,然后父和子都将调用第二次fork。父进程将产生子进程C,子进程将产生子进程D。结果是4个进程: A、B、C、D。
A ---- B
| |
C D由于您的打印将被缓冲,直到刷新到stdout,并且每个派生进程都会获得此缓冲区的副本,因此将打印四个"do“(check @ilkkachu回答)。
如果你打算只有一个" do ",你应该这样做:
pid_t pid = fork();
if (pid > 0){
printf(" do ");
printf(" ma ");
} else {
printf(" to \n");
}基本上,将fork()的返回存储在一个变量中,而不是在"if“语句中调用fork两次。
发布于 2017-05-09 23:12:15
因为默认情况下标准输出是行缓冲的(如果将其重定向到文件或管道,则是完全缓冲的)。
第一个printf没有换行符,所以它只将字符串do添加到C库内部的缓冲区中。在第一个fork上,复制整个过程,包括该缓冲区。然后其中一个副本将ma添加到它的缓冲区中,并且两个副本都被复制(因为两个进程都再次调用fork,而不仅仅是父进程或子进程)。
最后,调用printf(" to \n ")或printf("\n"),生成一个换行符,该换行符触发对缓冲区中任何内容的实际写入。
您可以使用fflush(stdout)强制C库在派生之前输出任何缓冲数据,也可以使用setbuf(stdout, NULL)完全禁用缓冲。
https://stackoverflow.com/questions/43872335
复制相似问题