【问题标题】:In double fork, why can't grandchild exit before child exit?在双叉中,为什么孙子退出之前不能退出?
【发布时间】:2018-11-12 14:19:18
【问题描述】:

双叉

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

因此,双叉只需要父进程等待子进程,子进程在fork孙子进程后立即退出,孙子进程作为后台进程负责真正的任务。

上下文

根据 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进行收割,父进程仍然不需要照顾。

这不是实现了使用双叉的最初目标吗?

【问题讨论】:

    标签: unix fork


    【解决方案1】:

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

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

    1. 如果孙子调用getppid其原始父级退出之前,则getppid 返回不是 pid 1 的内容。
    2. 如果孙子调用getppid其原始父级退出后,则getppid 返回 1。

    示例程序的目的是实现#2。所以它需要确保在孙子调用getppid之前原始父级已经退出。它通过在孙子中调用sleep(2) 来做到这一点。

    在一个真正的程序中,孙子不会在那里sleep(2)。它会做它的工作。

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

    【讨论】:

      猜你喜欢
      • 2018-07-20
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2018-09-11
      • 2011-01-21
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多