В двойной развилке почему внук не может выйти до выхода ребенка? - PullRequest
0 голосов
/ 12 ноября 2018

Двойная вилка

В моем понимании, двойная вилка используется, когда процесс хочет форкировать фоновый процесс, но 1. он не хочет ждать его И 2.фоновый процесс должен быть запущен после его выхода.

В результате двойная ветвь требует, чтобы родительский процесс ожидал только дочерний процесс, который должен завершиться сразу после разветвления процесса внука, а процесс внука отвечает за реальную задачу, посколькуфоновый процесс.

Context

Согласно этому отрывку из 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 секунды?Предположим, что он завершается до выхода дочернего процесса, он все равно будет получен при выходе из дочернего процесса в соответствии с этим вопросом , а родительский процесс по-прежнему не нуждается в этом.

Разве это не так?выполнить первоначальную цель использования двойной вилки?

1 Ответ

0 голосов
/ 12 ноября 2018

Цель этого примера - продемонстрировать, что родительский элемент внука становится процессом 1 (init) после выхода из исходного родительского элемента.

Чтобы продемонстрировать, что родитель внука становится процессом 1, внук вызывает getppid и печатает результат.

  1. Если внук звонит getppid до того, как выйдет его родитель, то getppid возвращает что-то, что не pid 1.
  2. Если внук вызывает getppid после того, как вышла его первоначальная родительская функция, тогда getppid возвращает 1.

Цель программы-примера - заставить # 2 произойти. Поэтому необходимо убедиться, что исходный родительский файл завершился до того, как внук позвонит getppid. Он делает это, вызывая sleep(2) у внука.

Внук в реальной программе не будет sleep(2) там. Он просто сделал бы свою работу.

Поскольку это игрушечная программа, для внука нет никакой реальной работы.

...