I have a piece of code that looks like this:
import subprocess
retcode = subprocess.call(["java","test","string"])
print "Exited with retcode " + str(retcode)
What I'm trying to do (and wondering if its possible) is to make sure
that any children (and any descendants) of this process is killed when
the main java process is killed (or dies).
How do I do this in windows, linux and OSX?
I don't think that you can do it reliably on any of those platforms.
Consider: A spawns B, B spawns C, C spawns D, B and C terminate. There is
no information available to tie D to A. A knows that it spawned B, and D's
PPID is C, but C no longer exists so you can't tell that B spawned C.
Process groups won't help, as subprocess.Popen() doesn't put the child
into a new process group, so all of its descendents will share the PGID of
the Python process and any children spawned from it. Even it did use a new
process group, the descendents might have different process groups (quite
likely if the initial child is a shell script, as the shell executes each
"command" in a new process group).
If you avoid the subprocess module and use os.fork(), the child can
create a new session by fork()ing again, and having the grandchild call
os.setsid(). All descendents will share this session unless they
explicitly create a new session (and you probably shouldn't be killing any
descendents which explicitly create a new session).
Another option is if to create the child with std{in,out,err} set to a
descriptor created for that specific child. Descendents inherit their
descriptors unless explicitly changed. The same applies to the CWD, and
(by convention) the environment. On Linux, you can discover a process'
descriptors, cwd and environment via the /proc filesystem.