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/
-~----------~----~----~----~------~----~------~--~---

Reply via email to