4

In python3 I am creating forked child processes, which I exit - I think - correctly. Here is some code example:

import os

child_pid = os.fork()
if child_pid == 0:
    print("I am in the child with PID "+str(os.getpid()))
    # doing something
    a = 1+1
    print("Ending child with PID "+str(os.getpid()))
    os._exit(0)
else:   
    #parent process      
    os.waitpid(-1, os.WNOHANG)
    import time
    for x in range(100):
        time.sleep(1)
        print("waiting...")                                        

Now, as the child process seems to be ended, it still can be seen as a 'defunct' process (while the parent process is still running). How to really get rid of that ended child process? How to change the code?

Alex
  • 41,580
  • 88
  • 260
  • 469
  • 1
    By defunct do you mean it's a zombie process? Your parent needs to wait on the child to get it's exist status, then it will go away. See http://stackoverflow.com/questions/13870945/how-can-i-prevent-a-child-process-to-not-become-a-zombie-if-parent-exits – pcarter Aug 04 '16 at 19:04
  • 1
    Replacing `os._exit(0)` by `sys.exit(0)` does not change the situation. And adding a command `os.waitpid(-1, os.WNOHANG)` in the parent process does not change the situation. A 'defunct' process still exists! – Alex Aug 04 '16 at 19:04
  • @pcarter: See my command, your suggestion does not seem to work ... – Alex Aug 04 '16 at 19:05
  • 1
    You can't use `WNOHANG`. That returns immediately even if the child hasn't already exited. You have to do a `wait` that doesn't return until the child does exit and gives you the child's exit code. – pcarter Aug 04 '16 at 19:10
  • So the parent process has to wait until the child finishes? – Alex Aug 04 '16 at 19:12

1 Answers1

5

You can use the double fork idiom if you don't want the parent to wait. (See What is the reason for performing a double fork when creating a daemon?)

The basic idea is for the parent process (call it P) to fork a child (C1) that immediately forks again to create another child (C2) and then exits. In this case, since the parent of C2 is dead, the init process will inherit C2 and wait on it for you. You will still have to wait on C1 in the P process or C1 will be a zombie. However, C1 only runs for a very short time, so the P process will not wait long. Your code running C2 can then take as much time as it wants and doesn't care if it finishes before or after P.

Another idea is to handle the SIGCHILD signal that occurs when a child has exited. From https://mail.python.org/pipermail/tutor/2003-December/026748.html

import os,signal

def handleSIGCHLD():
  os.waitpid(-1, os.WNOHANG)

signal.signal(signal.SIGCHLD, handleSIGCHLD)
Community
  • 1
  • 1
pcarter
  • 1,516
  • 14
  • 21