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