Using a signal to terminate a programm running with an asyncore loop

david at quanterium.zzn.com david at quanterium.zzn.com
Fri Feb 8 12:42:33 EST 2008


On Feb 8, 7:04 am, Larry Bates <larry.ba... at websafe.com> wrote:
> da... at quanterium.zzn.com wrote:
> > I'm developing a program that runs using an asyncore loop.  Right now
> > I can adequately terminate it using Control-C, but as things get
> > refined I need a better way to stop it.  I've developed another
> > program that executes it as a child process using popen2.Popen4().  I
> > was attempting to use signals to stop it (using os.kill()) but I keep
> > running into a problem where sending the signal causes an infinite
> > loop of printing the message "warning: unhandled exception".  This
> > message appears to be coming from asyncore.py.
>
> > Searching online I've found this old post that describes setting up a
> > signal handler using signal.signal():
>
> >http://mail.python.org/pipermail/medusa-dev/2000/000571.html
>
> > I've tried it but I don't see any indication that my handler method is
> > being called.  My best guess is that something somewhere else is
> > overriding my signal handling callbacks and sending the signals
> > elsewhere until they make their way into asyncore where they cause the
> > error message.
>
> > Any other ideas on how to get this to work?  If there's a different
> > signal I can use that other code won't override, that's fine (I don't
> > care what the signal is, as long as I can catch it).  Or perhaps there
> > is something different I can do?  The program, at present, doesn't
> > have much in the way of an internal shutdown mechanism.
>
> > I'm using Python 2.5.1 on Fedora 8; the program does not need to be
> > portable to Windows.
>
> > - David
>
> > (p.s. please post replies on the list; this email address doesn't work
> > so I won't see any replies sent directly to me)
>
> Please share a little of the code you used to "catch" the signal.  What
> signal(s) are you catching?  What kill level are you sending (these have to
> match up).  I've used this quite successfully in some of my programs.
>
> -Larry

Sure.  First, here is the signal I'm sending, from the parent process:

os.kill(self.child.pid, signal.SIGTERM)

self.child is the popen2.Popen4 object returned from creating the
child process.

In the child process, one of the first things in the "main" section
(if __name__ == '__main__':) is to set up the signal handler:

signal.signal(signal.SIGTERM, handle_shutdown_signal)

handle_shutdown_signal looks a lot like Sam Rushing's example code
from his 2000 post, though I didn't see much of a reason to have the
callback function turn around and call another function, so I combined
them:

SHUTDOWN_PERFORMED = False

def handle_shutdown_signal(signum, frame):
   global SHUTDOWN_PERFORMED
   print 'in shutdown handler, caught signal', signum #diagnostic msg
   if not SHUTDOWN_PERFORMED:
      #do some stuff
   asyncore.socket_map.clear()
   SHUTDOWN_PERFORMED = True
   raise asyncore.ExitNow

I also tried replacing the raise asyncore.ExitNow command with a
simple exit() call but that didn't help.

I've also tried using SIGHUP and SIGKILL and they didn't seem to make
a difference.

- David



More information about the Python-list mailing list