I've run into an "opportunity" in a Python application using threads and signals. Basically, there is a main process that spawns off a child thread that loops forever. In between iterations, the child thread sleeps for X seconds. All the while, the main thread loops forever doing its thing and also sleeps in between iterations (see the code at the end this message). Normally the application would be daemonized before the main process starts up. Hence, during a system shutdown or stoppage of the daemon, it's desired that the daemon catch a few signals (TERM/INT) and perform a few cleanup routines. According to the Python docs, only the main thread will receive signals. The problem I have, on FreeBSD systems, is that the sleep function in the child gets interrupted and the signal never gets handled until the main thread's sleep concludes. It works as expected on a Linux box (main thrd's sleep is interrupted). Sample output from multiple systems is directly below.
Just looking for insight from others in the know. Thanks, Chad Linux 2.6.17 ------------------------------------------------------------------------ test_bed$ python2.5 ./thrd_test.py Starting up MainThread.run(): 14332 MainThread before sleep(15) ChildThread.run(): 14332 ChildThread before sleep(10) Received signal 2 <-- Interrupted here (Ctrl-C), correctly flag: True interrupts sleep in main thread flag: False MainThread after sleep(15) Shutting down test_bed$ python2.4 ./thrd_test.py Starting up MainThread.run(): 14338 MainThread before sleep(15) ChildThread.run(): 14338 ChildThread before sleep(10) Received signal 2 <-- Interrupted here (Ctrl-C), correctly flag: True interrupts sleep in main thread flag: False MainThread after sleep(15) Shutting down test_bed$ FreeBSD 4.11, 6.1, and 6.2 ------------------------------------------------------------------------ bash-2.05b# python2.5 ./thrd_test.py Starting up MainThread.run(): 65930 ChildThread.run(): 65930 ChildThread before sleep(10) MainThread before sleep(15) ^CChildThread after sleep(10) <-- Interrupted here (Ctrl-C), but ChildThread before sleep(10) interrupts the child thrd's sleep ChildThread after sleep(10) ChildThread before sleep(10) Received signal 2 <-- Main sleep concludes and then the flag: True signal gets handled flag: False MainThread after sleep(15) Shutting down bash-2.05b# #--- CODE BEGIN ---# #!/usr/bin/env python import os import sys import time import signal import threading def sigHandle(signo, stkframe): print "Received signal ", signo print "flag: ", mthrd.flag.isSet() mthrd.flag.clear() print "flag: ", mthrd.flag.isSet() class ChildThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): print "ChildThread.run(): ", os.getpid() while (True): print "ChildThread before sleep(10)" time.sleep(10) print "ChildThread after sleep(10)" class MainThread(object): def __init__(self): self.flag = threading.Event() self.cthrd = ChildThread() self.cthrd.setDaemon(True) def run(self): print "MainThread.run(): ", os.getpid() self.flag.wait() self.cthrd.start() while (self.flag.isSet()): print "MainThread before sleep(15)" time.sleep(15) print "MainThread after sleep(15)" return # or cleanup routine if __name__ == "__main__": # Normally, the process is daemonized first. That's been # left out for testing purposes. signal.signal(signal.SIGINT, sigHandle) signal.signal(signal.SIGQUIT, sigHandle) signal.signal(signal.SIGTERM, sigHandle) mthrd = MainThread() print "Starting up" mthrd.flag.set() mthrd.run() print "Shutting down" sys.exit(0) #--- CODE END ---# -- http://mail.python.org/mailman/listinfo/python-list