Killing all child processes?
Martin Barnard
martinb at otenet.gr
Wed Apr 24 03:51:48 EDT 2002
Shouldn't you be looking into each child process having a handler to
pass on any SIG events it receives from STDIN (or parent)?
e.g. for each child process, take a PID and store it.
If parent receives a SIG event, then pass it down to child processes.
Each child process should have the same handler code in also (possibly
with a signal to parent if it quits, so that the list of child processes
is current for each parent).
Sorry if it sounds a little strange, I've just woken up, and am rambling
a little :)
Let's see if I can visualise:
Parent_1
|
____|____
| |
Child1 Child2
|
Child3
Now, if I send a SIGKILL to Parent_1, it will pass on <SIGKILL> to
Child1 and Child2. Child1 will pass on <SIGKILL> to Child3 via the same
mechanism.
The only potential problem would be if a child branch died before hand,
and the PID was taken by another process that Parent_1 could kill (same
user).
Hope this helps, if not, just ignore my waffling.
Martin.
On Wed, 2002-04-24 at 05:23, Kevin wrote:
> 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."
> --
> http://mail.python.org/mailman/listinfo/python-list
>
--
Experience is that marvelous thing that enables you recognize a mistake
when you make it again.
-- F. P. Jones
More information about the Python-list
mailing list