Windows+Python3.7环境下Ctrl+C无法终止运行中Thread的解决方案咨询
问题根因
Windows平台的线程、信号处理机制和类Unix(Ubuntu、macOS)系统存在差异:
- 主线程调用无超时的
threading.Thread.join()方法时,会完全阻塞主线程的信号响应流程,无法接收处理Ctrl+C触发的SIGINT信号 - 即使子线程被设置为守护线程,只要主线程一直卡在
join()调用没有返回,进程就不会触发退出逻辑
解决方案
核心思路是规避无超时的join()调用,同时给子线程增加可控的终止标志,实现优雅退出:
- 给子线程新增运行状态标志,替换硬编码的
while True循环判断条件,退出时可以主动通知子线程结束循环 - 主线程改用带短超时的循环
join()调用,两次join()的间隙主线程可以正常响应信号 - 捕获Ctrl+C触发的
KeyboardInterrupt异常后,先通知子线程终止,等待子线程安全退出后再结束主进程
修改后的可运行代码如下:
import time, threading class MainClass(threading.Thread): def __init__(self): super().__init__() # 子线程运行状态标志 self.running = True def run(self): while self.running: time.sleep(1) print("Looping") # 提供终止子线程的公开方法 def stop(self): self.running = False if __name__ == '__main__': a = MainClass() a.daemon = True a.start() try: # 循环带超时join,每次超时后主线程恢复运行,可以响应信号 while a.is_alive(): a.join(timeout=0.5) except KeyboardInterrupt: print("收到终止信号,正在退出...") # 通知子线程结束循环 a.stop() # 等待子线程执行完当前逻辑后退出 a.join() print("程序已优雅终止")
内容的提问来源于stack exchange,提问作者agjc
相关产品推荐
相关产品推荐

