This probably has an easy answer, but why not have a single process that monitors all children processes (instead of one per child).
Robert On Nov 8, 2006, at 1:17 AM, William Stein wrote: > Hi, > > I wrote an interesting little Python script, which I think will > totally > solve our "bad processes getting left around" problem. It's > actually a > very simple general purpose shell script, so I'm going to post it. > > The idea is that when SAGE spawns a process, it also spawns a monitor > that watches to see if the parent sage process disappears -- if so, it > kills the child process. It watches every five seconds. > > This monitor processes uses "0%" resources and 2MB memory on my > laptop. > > This will be in SAGE-1.5. > > #!/usr/bin/env python > > # this goes in <SAGE_ROOT>/local/bin/sage-monitor > > import os, time, sys > > def check_usage(): > v = sys.argv > if len(v) != 4: > print "Usage: sage-monitor <master pid> <subprocess pid> > <interval>" > print "Runs the shell command checking every interval > seconds" > print "to see if there is a process with the given master > pid." > print "If not kill -9 the given subprocess pid and > terminate." > print "Also, if at any point the subprocess vanishes, then > this" > print "program exits." > sys.exit(1) > > def process_is_running(pid): > try: > os.kill(pid,0) > except OSError: > # This means the process is not running > return False > return True > > def main(): > v = sys.argv > pid = int(v[1]) > subprocess = int(v[2]) > interval = int(v[3]) > > while True: > if not process_is_running(subprocess): > sys.exit(0) > if not process_is_running(pid): > # clean up house by killing subprocess > try: > os.killpg(subprocess, 9) > except OSError, msg: > pass > try: > os.kill(subprocess, 9) > except OSError, msg: > pass > sys.exit(0) > #end if > time.sleep(interval) > > if __name__ == '__main__': > check_usage() > main() > > ------------------------------------------------------------ > > # HG changeset patch > # User William Stein <[EMAIL PROTECTED]> > # Date 1162976220 28800 > # Node ID d49c043b5d80d25a524527dda1bf345b9b1dd97d > # Parent 34bbca760915c3aa763f93cd8f22a1f6ae05d941 > Added starting a monitor shadow process to make sure any spawned > processes > are cleaned up properly on exit, even if the master SAGE process is > kill > -9'd. Cool! > > diff -r 34bbca760915 -r d49c043b5d80 sage/interfaces/expect.py > --- a/sage/interfaces/expect.py Tue Nov 07 09:03:48 2006 -0800 > +++ b/sage/interfaces/expect.py Wed Nov 08 00:57:00 2006 -0800 > @@ -37,6 +37,9 @@ import sage.misc.sage_eval > import sage.misc.sage_eval > > import quit > + > +import monitor > +EXPECT_MONITOR_INTERVAL=5 # kill any slave processes at most 5 > seconds > after parent dies. > > import sage.rings.coerce as coerce > from sage.misc.misc import SAGE_ROOT, verbose, SAGE_TMP_INTERFACE > @@ -230,12 +233,6 @@ class Expect(SageObject): > os.makedirs(dir) > os.chdir(dir) > > - # This _absolute call below programs around a bug in pexpect: > - # make a directory X with a subdirectory "magma" and cd > into X. > Then: > - #sage: import pexpect > - #sage: m = pexpect.spawn('magma') > - #sage: m.interact() # -- boom! > - > try: > cmd = _absolute(self.__command) > except RuntimeError: > @@ -248,6 +245,7 @@ class Expect(SageObject): > > try: > self._expect = pexpect.spawn(cmd, > logfile=self.__logfile) > + monitor.monitor(self._expect.pid, > EXPECT_MONITOR_INTERVAL) > > except (pexpect.ExceptionPexpect, pexpect.EOF, IndexError): > self._expect = None > diff -r 34bbca760915 -r d49c043b5d80 sage/interfaces/monitor.py > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/sage/interfaces/monitor.py Wed Nov 08 00:57:00 2006 -0800 > @@ -0,0 +1,17 @@ > +##################################################################### > ########## > +# SAGE: System for Algebra and Geometry Experimentation > +# Copyright (C) 2005, 2006 William Stein <[EMAIL PROTECTED]> > +# Distributed under the terms of the GNU General Public License > (GPL) > +# The full text of the GPL is available at: > +# http://www.gnu.org/licenses/ > +##################################################################### > ########## > + > + > +import os > + > +PID = os.getpid() > + > +def monitor(pid, interval): > + cmd = 'sage-monitor %s %s %s &'%(PID, pid, interval) > + os.system(cmd) > + > > > --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---