KeyboardInterrupt
异常仅在每个进程的主线程中引发。但是该方法Thread.join
阻塞了调用线程,包括 KeyboardInterrupt
异常。这就是为什么Ctrl+C似乎没有效果。
解决您的问题的一个简单方法是使方法Thread.join
超时以解除阻塞KeyboardInterrupt
异常,并使子线程守护进程以让父线程在退出时将其杀死(非守护子线程不会被杀死,而是在退出时由其父线程加入):
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
如果您控制子线程的代码,更好的解决方案是通知子线程优雅退出(而不是像简单的解决方案那样突然退出),例如使用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