How to kill a child thread with Ctrl+C? How to kill a child thread with Ctrl+C? multithreading multithreading

How to kill a child thread with Ctrl+C?


If you want to have main thread to receive the CTRL+C signal while joining, it can be done by adding timeout to join() call.

The following seems to be working (don't forget to add daemon=True if you want main to actually end):

thread1.start()while True:    thread1.join(600)    if not thread1.isAlive():        break


The problem there is that you are using thread1.join(), which will cause your program to wait until that thread finishes to continue.

The signals will always be caught by the main process, because it's the one that receives the signals, it's the process that has threads.

Doing it as you show, you are basically running a 'normal' application, without thread features, as you start 1 thread and wait until it finishes to continue.


KeyboardInterrupt exceptions are raised only in the main thread of each process. But the method Thread.join blocks the calling thread, including KeyboardInterrupt exceptions. That is why Ctrl+C seems to have no effect.

A simple solution to your question is to make the method Thread.join time out to unblock KeyboardInterrupt exceptions and make the child thread daemonic to let the parent thread kill it at exit (non-daemonic child threads are not killed but joined by their parent at exit):

def main():    try:        thread = threading.Thread(target=f)        thread.daemon = True  # let the parent kill the child thread at exit        thread.start()        while thread.is_alive():            thread.join(1)  # time out not to block KeyboardInterrupt    except KeyboardInterrupt:        print "Ctrl+C pressed..."        sys.exit(1)def f():    while True:        pass  # do the actual work

A better solution if you control the code of the child thread is to notify the child thread to exit gracefully (instead of abruptly like with the simple solution), for instance using a threading.Event:

def main():    try:        event = threading.Event()        thread = threading.Thread(target=f, args=(event,))        thread.start()        event.wait()  # wait without blocking KeyboardInterrupt    except KeyboardInterrupt:        print "Ctrl+C pressed..."        event.set()  # notify the child thread to exit        sys.exit(1)def f(event):    while not event.is_set():        pass  # do the actual work