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

Larry Bates larry.bates at websafe.com
Fri Feb 8 19:03:36 EST 2008


david at quanterium.zzn.com wrote:
> 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


When signal is caught handle_shutdown_signal is called.  At that point 
SHUTDOWN_PERFORMED will ALWAYS be False.  Normally all you do in this function 
is to set SHUTDOWN_PERFORMED to True and have a test somewhere in your main 
program loop that tests if SHUTDOWN_PERFORMED:...  I know that when you reach

if not SHUTDOWN_PERFORMED:

SHUTDOWN_PERFORMED will always be False so #do some stuff will get executed.

Setting SHUTDOWN_PERFORMED = True doesn't do any good unless you catch this back 
in the main program.

If I were you I would try to issue kill from console first to see if it works. 
Then try os.kill().

Hope this helps some.

-Larry



More information about the Python-list mailing list