How to make child process die after parent exits?

后端 未结 24 2235
天涯浪人
天涯浪人 2020-11-22 05:31

Suppose I have a process which spawns exactly one child process. Now when the parent process exits for whatever reason (normally or abnormally, by kill, ^C, assert failure o

24条回答
  •  星月不相逢
    2020-11-22 06:15

    Under Linux, you can install a parent death signal in the child, e.g.:

    #include  // prctl(), PR_SET_PDEATHSIG
    #include  // signals
    #include  // fork()
    #include   // perror()
    
    // ...
    
    pid_t ppid_before_fork = getpid();
    pid_t pid = fork();
    if (pid == -1) { perror(0); exit(1); }
    if (pid) {
        ; // continue parent execution
    } else {
        int r = prctl(PR_SET_PDEATHSIG, SIGTERM);
        if (r == -1) { perror(0); exit(1); }
        // test in case the original parent exited just
        // before the prctl() call
        if (getppid() != ppid_before_fork)
            exit(1);
        // continue child execution ...
    

    Note that storing the parent process id before the fork and testing it in the child after prctl() eliminates a race condition between prctl() and the exit of the process that called the child.

    Also note that the parent death signal of the child is cleared in newly created children of its own. It is not affected by an execve().

    That test can be simplified if we are certain that the system process who is in charge of adopting all orphans has PID 1:

    pid_t pid = fork();
    if (pid == -1) { perror(0); exit(1); }
    if (pid) {
        ; // continue parent execution
    } else {
        int r = prctl(PR_SET_PDEATHSIG, SIGTERM);
        if (r == -1) { perror(0); exit(1); }
        // test in case the original parent exited just
        // before the prctl() call
        if (getppid() == 1)
            exit(1);
        // continue child execution ...
    

    Relying on that system process being init and having PID 1 isn't portable, though. POSIX.1-2008 specifies:

    The parent process ID of all of the existing child processes and zombie processes of the calling process shall be set to the process ID of an implementation-defined system process. That is, these processes shall be inherited by a special system process.

    Traditionally, the system process adopting all orphans is PID 1, i.e. init - which is the ancestor of all processes.

    On modern systems like Linux or FreeBSD another process might have that role. For example, on Linux, a process can call prctl(PR_SET_CHILD_SUBREAPER, 1) to establish itself as system process that inherits all orphans of any of its descendants (cf. an example on Fedora 25).

提交回复
热议问题