我正在学习多进程,并且知道使用fork()时会创建子进程,并且子进程会获取父进程的堆栈,数据,堆和文本段的副本。
那么为什么下面的这段代码不显示两个“ hello”?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
static int idata = 111; /* Allocated in data segment */
int main(int argc, char *argv[])
{
int istack = 222; /* Allocated in stack segment */
pid_t childPid;
idata *= 2;
istack *= 2;
printf("hello\n");
switch (childPid = fork()) {
case -1:
printf("fork fail\n");
exit(0);
case 0:
idata *= 3;
istack *= 3;
break;
default:
sleep(3); // Give child a chance to execute
break;
}
/* Both parent and child come here */
printf("PID=%ld %s idata=%d istack=%d\n", (long) getpid(),
(childPid == 0) ? "(child) " : "(parent)", idata, istack);
exit(0);
}
结果是
你好
PID = 591(子级)idata = 666 istack = 1332
PID = 590(父级)idata = 222 istack = 444
为什么此代码不显示两个“ hello”?
答案 0 :(得分:4)
printf("hello\n");
发生在fork()
之前。
当输出是终端时,stdout
默认是行缓冲的,它输出1 hello
,因为stdout
在\n
上被刷新。
当输出重定向到文件或管道中时,stdout
默认情况下是块缓冲的,它会输出2个hello
,因为父进程和子进程都已缓冲hello
并且缓冲区将在exit()
上刷新。
答案 1 :(得分:0)
您要在调用printf("hello\n");
函数之前创建fork()
。
答案 2 :(得分:0)
跟踪程序流程。首先,只有一个进程执行该程序。此过程打印“ hello”。接下来,在switch语句内部有一个fork系统调用。现在有两个过程,父进程和子进程。子级是父级的克隆。除进程ID外,其他所有内容都相同。甚至下一条要执行的指令对于两者都是相同的。父级和子级都将执行下一个switch语句。这个孩子从来没有机会打印“你好”。