[linux] how to ensure that the child process exits when the parent process exits?

Posted by doozerdc on Fri, 11 Feb 2022 07:10:36 +0100

Video analysis related to linux server development:

linux kernel, implementation of process scheduler, fully fair scheduler CFS
Analysis of 10 classic interview questions, how does the technical direction determine the career direction

c/c++ linux server development free learning address: Senior architect of c/c++ linux background server

preface

When the child process exits, the parent process can receive the signal of the child process exit, which is convenient for management. However, sometimes when the parent process exits, the child process also exits. What should I do?

What happens to the child process when the parent process exits?

Generally, after the parent process exits, the child process will not be notified. At this time, the child process will become an orphan process and eventually be adopted by the init process. Let's take a look at this situation first.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

int main(void)
{
    pid_t pid;
    //fork a process
    pid = fork();
    //Creation failed
    if (pid < 0)
    {
        perror("fork error:");
        exit(1);
    }
    //Subprocess
    if (pid == 0)
    {
        printf("child process.\n");
        printf("child  pid:%d,parent pid:%d\n",getpid(),getppid());
        printf("sleep 10 seconds.\n");
        //Sleep for a period of time. Let the parent process exit first. For easy observation, sleep for 10s
        sleep(10);

        printf("now child pid: %d parent pid:%d\n",getpid(),getppid());
    }
    //Parent process
    else
    {
        printf("parent process.\n");
        sleep(1);
    }
    return 0;
}

In this program, in order to let the parent process exit first, the child process sleep for 10 seconds.
The operation results are as follows:

parent process.
child process.
child  pid:17433,parent pid:17432
sleep 10 seconds.
now child pid: 17433 parent pid:1658

It can be seen from the results that at first, the parent process id of the child process 17433 is 17432, but after 10 seconds, its parent process becomes 1658. What is the process of 1685?

$ ls -al /proc/1658/exe 
/proc/1658/exe -> /sbin/upstart

Because the environment I used was a ubuntu system with a graphical interface, I was eventually adopted not by the well-known init process, but by a process called / sbin/upstart. It can also be observed that this process is also the parent process of other system processes.

[article benefits] learning materials for C/C++ Linux server architects plus group 812855908 (materials include C/C + +, Linux, golang technology, Nginx, ZeroMQ, MySQL, Redis, fastdfs, MongoDB, ZK, streaming media, CDN, P2P, K8S, Docker, TCP/IP, collaboration, DPDK, ffmpeg, etc.)

How to ensure that when the parent process exits, the child process also exits?

In that case, how to ensure that when the parent process exits, the child process also exits? Perhaps we can establish a communication pipeline between the child process and the parent process. Once the communication is abnormal, it is considered that the parent process exits, and the child process also reclaims resources and exits. But it's not very serious to do so. Is there an existing function to help us do this? The prctl function can help us. In the first parameter, there is an option called PR_GET_PDEATHSIG:

  PR_SET_PDEATHSIG (since Linux 2.1.57)
          Set  the  parent  death signal of the calling process to arg2 (either a signal value in the range 1..maxsig, or 0 to clear).
          This is the signal that the calling process will get when its parent dies.  This value is cleared for the child of a fork(2)
          and (since Linux 2.4.36 / 2.6.23) when executing a set-user-ID or set-group-ID binary, or a binary that has associated capa‐
          bilities (see capabilities(7)).  This value is preserved across execve(2).

There are many contents. The main meaning is to set a signal. When the parent process exits, the child process will receive the signal.

Then, according to this, we can also give the child process an exit signal when the parent process exits. The program code is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <signal.h>
int main(void)
{
    pid_t pid;
    //fork a process
    pid = fork();
    //Creation failed
    if (pid < 0)
    {
        perror("fork error:");
        exit(1);
    }
    //Subprocess
    if (pid == 0)
    {
        /*When the parent process exits, it will receive SIGKILL signal*/
        prctl(PR_SET_PDEATHSIG,SIGKILL);
        printf("child process.\n");
        printf("child  pid:%d,parent pid:%d\n",getpid(),getppid());
        printf("sleep 10 seconds.\n");
        //Sleep for a period of time. Let the parent process exit first. For easy observation, sleep for 10s
        sleep(10);

        printf("now child pid: %d parent pid:%d\n",getpid(),getppid());
    }
    //Parent process
    else
    {
        printf("parent process.\n");
        sleep(1);
    }
    return 0;
}

Operation results:

parent process.
child process.
child  pid:17625,parent pid:17624
sleep 10 seconds.

As you can see, due to joining

prctl(PR_SET_PDEATHSIG,SIGKILL);

When the parent process exits, the child process will receive the SIGKILL signal, and the default action of the process receiving the signal is to exit. Therefore, it will not be seen as an orphan process and adopted by other processes in the end. It should be noted that this function is not supported by all systems.

summary

In some cases, we often need the co existence of the parent and child processes. When the child process exits, the parent process can capture the exit status of the child process through wait, but it is difficult for the child process to know when the parent process exits. Therefore, when the child process is fork ed initially, it indicates that when the parent process exits, the child process receives the SIGKILL signal and finally exits. In order to achieve the purpose of living and dying together.

Topics: C++ Linux Back-end Process