在用 python 编写多线程程序时,经常需要用 Ctrl + C 中止进程,可是大家都知道,在 python 中,除了主线程可以响应控制台的 Ctrl + C ,其他线程是无法捕获到的,也就是说,当主线程被中止后,其他线程也会被强制中止,这样线程们就没有机会处理自己还没有完成的工作。
而在实际应用中,我们可能会有这样的要求:
当按下 Ctrl + C 时,我们希望所有线程先处理完自己的任务,再主动停止
当所有线程停止后,主线程才终止
【这篇文章】提供了一种方法,我对其做了进一步改进,写了如下的代码,希望能起到抛砖引玉的作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import threading
class MyThread(object): def __init__(self, thread_num): self.thread_num = thread_num self.outLock = threading.Lock() self.threads = [] self.interruptEvent = threading.Event() def beginTask(self): for i in range(self.thread_num): t_name = str(i + 1) thread = threading.Thread(target=self.doSomething, kwargs={"t_name": t_name}) self.threads.append(thread)
for thread in self.threads: thread.start() self.interruptEvent.clear() while True: try: alive = False for thread in self.threads: alive = alive or thread.isAlive() if not alive: break except KeyboardInterrupt: self.interruptEvent.set() def doSomething(self, t_name): self.outLock.acquire() print u"线程 %s 已启动" % t_name self.outLock.release() while True: try: if self.interruptEvent.isSet(): raise KeyboardInterrupt except KeyboardInterrupt: self.outLock.acquire() print u"用户强制中止主线程,线程 %s 已中止" % t_name self.outLock.release() break self.outLock.acquire() print u"线程 %s 已停止" % t_name self.outLock.release() if __name__ == "__main__": t = MyThread(5) t.beginTask()
|
程序启动后,如图 1 所示:

按下 Ctrl + C 后,如图 2 所示:

这样各个线程都有机会处理自己的任务后主动停止,随后主线程再终止。