进程执行结束后fork()输出

时间:2012-08-03 19:24:49

标签: c fork

请考虑以下代码段:

int main()
{
    fork();
    fork();
    fork();
    printf("Hello World\n");
}

我得到了输出:[ubuntu 12.04]

aashish@aashish-laptop:~$ ./a.out
Hello World
Hello World
Hello World
aashish@aashish-laptop:~$ Hello World <---------------------------
Hello World
Hello World
Hello World
Hello World

为什么&#34; Hello Word&#34;在流程执行结束后输出?

4 个答案:

答案 0 :(得分:5)

简短的回答是,您正在创建多个进程,这些进程相互之间异步运行。答案如下:

在shell提示符下键入 ./ a.out 时,会创建一个运行程序的进程。我们称之为过程1。

进程1调用fork()。这将创建一个新的子进程,进程2,并且在第一次fork()调用之后,1和2都继续执行,继续执行第二次fork()调用。进程1创建子进程3,进程2创建子进程4.所有四个进程从第二个fork()之后继续进行到最后的fork()调用。流程1创建流程5;流程2创建流程6;流程3创建流程7;和流程4创建流程8。

non-artist's rendering of process hierarchy

请注意,这些流程编号是任意的:不能保证按顺序创建它们。

一旦第一个fork()被执行,异步就会发挥作用。系统不保证关于孩子安排父母。从理论上讲,孩子可以在父母继续之前跑完,父母可以在孩子获得任何资源之前完成。最可能的情况是位于中间位置:原始进程与其后代共享资源,因此所有进程同时运行。

最后一块拼图是因为shell正在等待进程1完成。 进程1. shell不知道(或关心)进程1是否已启动其他进程。因此,当Process 1完成时,shell会显示提示。事实上,进程1的一些后代还没有达到printf()语句。当他们到达那里时,shell已经显示了它的提示。

要进一步探讨此问题,您可能需要尝试将 fork()调用更改为 printf(“%d \ n”,fork()); 和/或者将 printf(“Hello World \ n”)更改为 printf(“你好,来自pid%d \ n”,getpid())

答案 1 :(得分:3)

第二个shell提示之后的“Hello World”输出来自分叉进程,而不是来自shell(你)发起的那个。

答案 2 :(得分:0)

那是因为你制作了1个fork(2),然后你再次分叉(4),然后再次(8)然后为每个fork打印Hello世界。这就是为什么你有8个输出。

答案 3 :(得分:0)

int main() {
    pid_t c[3];
    int i, n = 0;
    for (i = 0; i < 3; ++i) {
        switch ((c[n] = fork())) {
        case 0:  break;
        case -1: perror("fork"); exit(EXIT_FAILURE);
        default: ++n;
        }
    }
    printf("[%d] Hello World\n", (int)getpid());
    // Without waiting, some children may still be running when the
    // parent exits. This makes it look like output is generated
    // after the process is over, when in fact not all the processes
    // are done yet.
    //
    // The process is not really finished until its children are
    // finished. The wait call waits on a child process to finish.
    for (i = 0; i < n; ++i) wait(0);
    return 0;
}