在双叉中,为什么孙子不能在孩子退出之前退出?

时间:2018-11-12 14:19:19

标签: unix fork

双叉

在我的理解中,当进程想要派生后台进程时使用双叉,但是1.它不想等待它,并且2.退出后应该获得后台进程。

因此,双叉仅需要父进程等待子进程,该子进程应在分叉孙进程之后立即退出,而孙进程则将真实任务作为后台进程负责。

上下文

根据APUE的摘录,孙子睡2秒以确保其父(子)在退出前退出,这样它将成为孤儿,并且init会照顾它并在退出时收割它。

#include "apue.h"
#include <sys/wait.h>

int
main(void)
{
    pid_t   pid;

    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {      /* first child */
        if ((pid = fork()) < 0)
            err_sys("fork error");
        else if (pid > 0)
            exit(0);    /* parent from second fork == first child */

        /*
         * We're the second child; our parent becomes init as soon
         * as our real parent calls exit() in the statement above.
         * Here's where we'd continue executing, knowing that when
         * we're done, init will reap our status.
         */
        sleep(2);
        printf("second child, parent pid = %ld\n", (long)getppid());
        exit(0);
    }

    if (waitpid(pid, NULL, 0) != pid)   /* wait for first child */
        err_sys("waitpid error");

    /*
     * We're the parent (the original process); we continue executing,
     * knowing that we're not the parent of the second child.
     */
    exit(0);
}

问题

为什么孙子进程需要睡眠2秒钟?假设它在子进程退出之前退出,但根据this question子进程退出时它仍然会被收割,而父进程仍然不需要照顾它。

不能达到使用双叉的最初目标吗?

1 个答案:

答案 0 :(得分:1)

该示例的目的是演示孙子的父级在其原始父级退出后成为进程1(init)。

为证明孙子的父级成为进程1,孙子调用getppid并打印结果。

  1. 如果孙子在离开原父之前叫getppid 之前,则getppid返回的不是pid 1。
  2. 如果孙子在其原父母离开后打电话给getppid ,则getppid返回1。

示例程序的目的是使#2发生。因此,需要确保原始父级在孙子级调用getppid之前已经退出。它是通过在孙子中调用sleep(2)来实现的。

在真实程序中,孙子不会sleep(2)在那里。它将完成其工作。

由于这是一个玩具程序,所以孙子没有真正的工作要做。