Catch Keyboard Interrupt in program that is waiting on an Event

Update: On the current Python 3 finished_event.wait() works on my Ubuntu machine (starting with Python 3.2). You don't need to specify the timeout parameter, to interrupt it using Ctrl+C. You need to pass the timeout parameter on CPython 2.

Here's a complete code example:

#!/usr/bin/env python3
import threading

def f(event):
    while True:
        pass
    # never reached, otherwise event.set() would be here

event = threading.Event()
threading.Thread(target=f, args=[event], daemon=True).start()
try:
    print('Press Ctrl+C to exit')
    event.wait()
except KeyboardInterrupt:
    print('got Ctrl+C')

There could be bugs related to Ctrl+C. Test whether it works in your environment.


Old polling answer:

You could try to allow the interpreter to run the main thread:

while not finished_event.wait(.1): # timeout in seconds
    pass

If you just want to wait until the child thread is done:

while thread.is_alive():
    thread.join(.1)

If you want to avoid polling, you can use the pause() function of the signal module instead of finished_event.wait(). signal.pause() is a blocking function and gets unblocked when a signal is received by the process. In this case, when ^C is pressed, SIGINT signal unblocks the function. Note that the function does not work on Windows according to the documentation. I've tried it on Linux and it worked for me.

I came across this solution in this SO thread.