Killing all child processes?
Kevin
kfrederick at bigfoot.com
Tue Apr 23 22:23:36 EDT 2002
Hi all,
I can't seem to get my python program to kill all the child prcoesses
that it may fork. Is this possible?
I've researched usenet+the web and read subproc.py from
ftp.python.org, but still no go.
My latest attempt was a python script that forks itself, uses setpgid,
then the child does an execl(). The execl'd program creates some
children. Meanwhile, the parent decides time is up on the child and
tries to kill everything, but my os.kill(pid,9) only succeeds in
killing the child aka the execvp'd process.
There's another bug that I haven't yet addressed about the parent
waiting around when the child doesn't write to either of the pipes.
But that'd not my focus now, so don't worry about that; I just want
all the children to die.
My full code it at the bottom. Hints, anyone? This is on Linux and
FreeBSD.
Thanks,
Kevin
---Full code follows---
---- pcontrol.py below
#!/usr/bin/python
#
# pcontrol.py
#
import os
import sys
import signal
_alarm = "request timed out"
time = 5
cmd="sh1.sh"
###########################################################
def alarm_handler(a , b):
global _alarm
signal.alarm(0)
raise _alarm
###########################################################
# Okay, let's do this the hard way: create two unnamed
# pipes for stdout/err. Then, fork this process, and the
# child becomes the new command and shoves their output
# onto the pipes, while the parent waits for the child to die.
# Create two named pipes
child_out_r, child_out_w = os.pipe()
child_err_r, child_err_w = os.pipe()
# Let's fork a child that gets replaced with the test process - krf
child_pid = os.fork()
if (child_pid != 0):
# We're the parent
os.close(child_out_w) # the parent won't read the pipes
os.close(child_err_w)
os.setpgid(child_pid, 0)
# Now do the timing...
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(time)
try:
child_pid, child_status = os.waitpid(child_pid, 0); # wait for
child
except OSError:
print("OSError... did the executable time out?")
child_status = -1 # this is the same as a timeout for now
except _alarm:
print("Timed out")
# kill it!
os.kill(child_pid, 9)
child_status = -1 # timeout
signal.alarm(0) # clean up alarm
else:
# We're the child
os.setpgid(0, 0) # now the child is it's group leader (?)
# Redirect error to our pipes
os.close(child_out_r) # the child won't read the pipes
os.close(child_err_r)
os.dup2(child_out_w, sys.stdout.fileno())
os.dup2(child_err_w, sys.stderr.fileno())
# replace the process
os.execl(cmd, cmd) #strange, but execl->execv needs a second
arg...
# the child is no more... (assuming success)
print "Status = ", child_status
print "Child stdout [",os.read(child_out_r,999),"]"
print "Child stderr [",os.read(child_err_r,999),"]"
------- sh1.sh below
#!/bin/sh
echo "This is processs (1) $$."
sh2.sh &
sh3.sh &
sleep 600
echo "Process (1) $$ exiting."
------- sh2.sh below
#!/bin/sh
echo "This is processs (2) $$."
sleep 600
echo "Process (2) $$ exiting."
------- sh3.sh below
#!/bin/sh
echo "This is processs (3) $$."
sleep 600
echo "Process (3) $$ exiting."
More information about the Python-list
mailing list