1
import sys 
import time
import threading

class exThread(threading.Thread):
    def __init__(self, threadId):
        threading.Thread.__init__(self)
        self.threadId = threadId

    def run(self):
        try:
            while 1:
                pass
        except KeyboardInterrupt:
            print "Ctrl-C caught by thread"
        finally:
            print "Thread's finally clause being executed" 
            sys.exit() # Same as thread.exit()

cond = True
def func():
    pass

try:
    th = exThread(1)
    th.start()
    while True:
        if cond:
            func()
except KeyboardInterrupt:
    print "Ctrl-C caught by main thread"
    sys.exit(0)
finally:
    print "Executing the finally clause from main thread"

On executing above code, when I press Ctrl-C, the main thread exits after printing from its finally clause. Now, since the child thread is a non-daemon, it is still running in the try: except KeyboardInterrupt block. However, this child thread doesn't seem to respond to Ctrl-C, even though it is supposed to catch KeyboardInterrupt exception. Why?

gjain
  • 4,468
  • 5
  • 39
  • 47

1 Answers1

1

As far as I know, KeyboardInterrup is only raised in the main thread. To be able to stop the other threads, make them check for an event from time to time, and then exit voluntarily.

Another option is to mark the child thread as daemon=True so that it will auto-terminate when the main thread terminates:

th.daemon = True

Additional reading:

Community
  • 1
  • 1
Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111
  • Can you cite the docs for the first point you make? Because, at least for thread module (http://docs.python.org/2/library/thread.html), I quote "Threads interact strangely with interrupts: the KeyboardInterrupt exception will be received by an arbitrary thread. (When the signal module is available, interrupts always go to the main thread.)" – gjain Oct 06 '13 at 12:35
  • Daemon threads are not an option, since I need child threads to terminate gracefully – gjain Oct 06 '13 at 12:36
  • So use the exit event signalling approach then; about the doc: well you said it yourself: *"When the signal module is available, interrupts always go to the main thread."*... if `signal` is available, the main thread will get it; but I don't know what determines its availability. – Erik Kaplun Oct 06 '13 at 12:37