Suppose I've got a Python daemon that spawns a bunch of worker threads, waits 
for a singal (e.g. SIGTERM) and then shuts down the worker threads gracefully. 
What's the simplest way to do the signal handling portably across as many 
operating systems as possible (at least Linux and FreeBSD). Specifically, I'm 
interested in solutions where the main thread consumes no CPU, so no 
time.sleep(n) loops.

The most obvious solution (below) does not work with on FreeBSD, because the 
signal gets delivered to a different thread and signal.pause() doesn't return.

_shutdown = False

def sig_handler(signum, frame):
    print 'handled'
    global _shutdown
    _shutdown = True

if __name__ == '__main__':

    # Set up signal handling.
    signal.signal(signal.SIGTERM, sig_handler)

    # Start worker threads.
    workers = [Worker() for i in xrange(NUM_THREADS)]
    for worker in workers:
        worker.start()

    # Sleep until woken by a signal.
    while not _shutdown:
        signal.pause()

    # Shutdown work threads gracefully.
    for worker in workers:
        worker.shutdown()

Any ideas? I've attached a more complete code sample.

Thanks
Duncan Findlay


import signal
import threading

NUM_THREADS = 2

class Worker(threading.Thread):

    def __init__(self, *args, **kwargs):
        threading.Thread.__init__(self, *args, **kwargs)
        self._stop_event = threading.Event()

    def run(self):
        # Do something.
        while not self._stop_event.isSet():
            print 'hi from %s' % (self.getName(),)
            self._stop_event.wait(10)

    def shutdown(self):
        self._stop_event.set()
        print 'shutdown %s' % (self.getName(),)
        self.join()

_shutdown = False

def sig_handler(signum, frame):
    print 'handled'
    global _shutdown
    _shutdown = True

if __name__ == '__main__':

    # Set up signal handling.
    signal.signal(signal.SIGTERM, sig_handler)

    # Start worker threads.
    workers = [Worker() for i in xrange(NUM_THREADS)]
    for worker in workers:
        worker.start()

    # Sleep until woken by a signal.
    while not _shutdown:
        signal.pause()

    # Shutdown work threads gracefully.
    for worker in workers:
        worker.shutdown()
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to