为什么在使用多进程时此代码不打印两个“ hello”?

时间:2019-10-23 11:01:20

标签: c linux process multiprocessing

我正在学习多进程,并且知道使用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”?

3 个答案:

答案 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语句。这个孩子从来没有机会打印“你好”。