Wed Nov 12 16:59:37 EST 2008

Only the main thread handles signals in Python

I learned just now that only the main thread in python handles signals. Signals are caught and placed in a queue which is checked at the execution of each line of code. So in code like this:

LOG = True
while LOG:
    try:
        data = myqueue.get()
        print data
    except (KeyboardInterrupt, SystemExit):
        LOG = False

the program will block on the myqueue.get() call and not catch a Ctrl-C until something comes out of the queue. One must instead write it something like this:

LOG = True
while LOG:
    try:
        data = myqueue.get_nowait()
        print data
    except (KeyboardInterrupt, SystemExit):
        LOG = False
    except (Queue.Empty):
        continue

Here myqueue.get_nowait() will return immediately if nothing ins in the queue, raising a Queue.Empty exception, which I catch and gracefully ignore. Everything would be hunky-dory except even this code sometimes fails to quit properly with a Ctrl-C. The resulting traceback seems to focus on the myqueue.get_nowait() or the except (Queue.Empty) lines, indicating that the Keyboard Interrupt was caught in execution of these lines and therefore somehow not caught by the try statement. Why it’s not caught by the try statement I'm not sure yet.


Posted by vschmidt | Permanent link | File under: python