简体   繁体   中英

Python forked processes won't die

I've seen several questions like this one, but after trying various variants of checking if the children are alive and exiting the children processes, I simplified the problem and still it will not work.

Am I wrong in exiting a forked process with sys.exit(0)? Is there another way to kill it. The thing is, I cannot have the parent kill the processes since it won't know when they're done working.

At first I thought it was because a executed a system command before exiting ( Python run system command and then exit... won't exit ), but I've even removed that in the simplified version as given solution didn't work either.

Here's an example:

import sys
import os
import time

children = []

for i in range(0,3):    
    pid = os.fork()

    if pid == -1:
        continue
    elif pid == 0:
        # Do work...
        print 'Child %d spawned' % os.getpid()
        sys.exit(0)     
    else:
        children.append(pid)

time.sleep(5)
for pid in children:
    proc_path = '/proc/%d' % pid
    if not os.path.exists(proc_path):
        print 'Child %d is dead' % pid
    else:
        print 'Child %d is alive' % pid

This prints:

Child 27636 spawned
Child 27637 spawned
Child 27638 spawned
Child 27636 is alive
Child 27637 is alive
Child 27638 is alive

But child processes should be dead.

What causes these processes to become zombies in this case?

You have to wait() for the child-process.

Please add the following lines to get things corrected:

import sys
import os
import time

children = []

for i in range(0,3):    
    pid = os.fork()

    if pid == -1:
        continue
    elif pid == 0:
        # Do work...
        print 'Child %d spawned' % os.getpid()
        sys.exit(0)     
    else:
        children.append(pid)

time.sleep(5)

# ADD NEXT TWO LINES:
for pid in children:
    os.waitpid(pid, 0)

for pid in children:
    proc_path = '/proc/%d' % pid
    if not os.path.exists(proc_path):
        print 'Child %d is dead' % pid
    else:
        print 'Child %d is alive' % pid

The parent must wait() for the child. Please see man 2 wait for details.

In python you can handle those things with the subprocess module.

For child to disappear from PID table you need wait() on parent's side.

n_still_children_alive = len(children)
while n_still_children_alive > 0:
    pid, status = os.wait()
    print "Child %d died and joined" % pid
    n_still_children_alive -= 1

If you want to play around with multiprocessing in Python, you're much better of using multiprocessing module instead of using os module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM