12

How can I detect parent process death in Linux OS?

If in parent process called fork(), that create child process. In the parent process I can use system call wait() for waiting terminated child process, and getting its status.

But, I can't find info about how child process can detect parent process' death?

William Pursell
  • 204,365
  • 48
  • 270
  • 300
Simplex
  • 1,723
  • 2
  • 17
  • 26
  • possible duplicate of [How to make child process die after parent exits?](http://stackoverflow.com/questions/284325/how-to-make-child-process-die-after-parent-exits) – alk Aug 30 '12 at 10:45

3 Answers3

9

You can get the parent process id by calling getppid() and then sending signal 0 via kill(). A return code of 0 will indicate that the process is still alive.

As mentioned by @Ariel, getppid() will either return the pid of the original parent or that of init, which will be pid 1. So you either have to store the parent pid by calling getppid() at startup or later check if your parent has pid 1.

According to this answer on Linux you can also detect the death of the parent via prctl()'s PR_SET_PDEATHSIG option and a self-chosen signal.

Community
  • 1
  • 1
scai
  • 20,297
  • 4
  • 56
  • 72
  • 1
    All processes have a parent, it's not possible to not have a parent (i.e. `kill` will never return 0 for a pid from `getppid`). If the parent of a process dies it usually kills the children. If not, then the process will be adopted by init, which has pid 1 - so check for that. – Ariel Aug 30 '12 at 09:24
  • @Ariel that's right, either check for pid 1 or call getppid() directly at startup and store the parent pid so that you can check it via kill() later. – scai Aug 30 '12 at 09:26
  • 1
    You don't really need the `kill` - just call `getppid` again and see if it changed (although there is a potential race condition there, so also check for 1). – Ariel Aug 30 '12 at 09:28
  • 2
    I don't think, that constantly checking changing ppid it's good, idea. I need in asynchronous operation. I think, that using prctl() is optimal solution. – Simplex Aug 30 '12 at 09:34
  • Tried this, but for me on Linux getppid() returns >1 if parent dies. I don't think that some can assume this behavior. I decided to check if id changes. – timmornYE Apr 25 '14 at 07:05
  • Just curious, did you check whether the PID return by `getppid()` matches the PID of your init process? – scai Apr 25 '14 at 07:25
  • Erroneous to assume parent process is 1. That was in the good old init days before wise men from the east broke everything with systemd. Take getppid, paste it into /proc//cmdline and do strstr for systemd IF getppid did not return 1 in which case you are a good man running a proper Unix – Waslap Aug 19 '21 at 07:39
  • This method is inherently racy as process IDs are recycled. Do not rely on it – dmw Sep 18 '21 at 13:03
  • @dmw True. However this is only a problem if either `/proc/sys/kernel/pid_max` is set to a very low value or if you have a really large number of processes running. The Kernel only reuses PIDs if `pid_max` is reached, then a wraparound happens. On a typical Linux system this shouldn't become racy since PID reuse either doesn't happen at all or with enough time in between. However YMMV, so this is still an important hint. – scai Sep 20 '21 at 05:55
5

If both the parent and child process are under your control for their lifetime, the most portable method is to share one half of a pipe or socket with the parent.

  1. Prior to fork, open a pipe() or socketpair().
  2. After fork,
    1. in the parent, close the read end of the pipe, or the first socket.
    2. in the child, close the write end of the pipe, or the second socket.
  3. In the parent, stash the remaining file descriptor away and forget about it.
  4. In the child, use any of the multiplexed IO methods (select, poll, etc.) to test the descriptor for readability
  5. If the descriptor becomes readable, the parent is almost certainly dead, or some rare bug caused a stray write, which you can check for by calling read(). If the parent really was dead, read() will return 0 bytes.

The advantage of this method is that it completely avoids signals, which are one of the hardest to master mechanisms in UNIX, and provides a waitable descriptor that can easily be integrated with a network multiplexer or GUI event loop.

dmw
  • 1,528
  • 16
  • 20
  • This not only avoids signals. It also can be used when you can't use getppid() to determine if the parent process has died. For example, if you are creating a watchdog process. Watchdog processes daemonize themselves forking child 1, then child 1 forks child 2, then child 1 dies. Now child 2 has parent process ID = 1. So getppid() won't work there. The only way to do it by using pipes or sockets to determine if the main process has died. – Steve Weigand Aug 31 '21 at 16:11
3

In my Ubuntu 16.04.1 LTS getppid() returns no "1" but id of process "/sbin/upstart --user" after parent kill, so checking getppid() == 1 will not work and getppid() should be saved at child start and later compared.