如何利用主进程的KeyboardInterrupt终止所有后台子进程?
解决主进程捕获
KeyboardInterrupt时终止所有子进程的问题 这个问题的核心是:当你按下Ctrl+C时,只有主进程会收到KeyboardInterrupt信号,而子进程作为独立的进程实例,不会自动接收到这个信号。原代码里主进程启动子进程后直接结束,没有处理中断信号,导致子进程变成孤儿进程继续在后台运行。
要解决这个问题,我们需要在主进程中主动捕获中断信号,然后统一终止所有子进程。下面是修改后的完整代码:
import time from multiprocessing import Process def process(proc_n): while True: try: print(f"Process {proc_n} is running...") # 可选:添加日志方便观察进程状态 time.sleep(0.5) except KeyboardInterrupt: print(f"Process {proc_n} received interrupt, exiting...") break except Exception as e: print(f"Process {proc_n} error: {e}") def main(): # 将进程实例存入列表,方便统一管理,避免单独维护多个变量 processes = [ Process(target=process, args=(1,)), Process(target=process, args=(2,)), Process(target=process, args=(3,)), Process(target=process, args=(4,)) ] # 批量启动所有子进程 for p in processes: p.start() try: # 主进程等待所有子进程正常结束 for p in processes: p.join() except KeyboardInterrupt: # 捕获到中断信号后,主动终止所有存活的子进程 print("\nMain process received interrupt, terminating all child processes...") for p in processes: if p.is_alive(): p.terminate() # 可选:等待子进程完全退出,确保资源释放 p.join() if __name__ == '__main__': main()
关键修改说明:
- 统一管理子进程:把所有子进程实例存入列表,替代单独的
p1-p4变量,方便批量执行启动、等待、终止操作。 - 主进程捕获中断信号:通过
try-except块捕获KeyboardInterrupt,确保按下Ctrl+C时主进程不会直接退出,而是进入终止子进程的逻辑。 - 主动终止子进程:调用
p.terminate()方法向子进程发送终止信号(Unix下是SIGTERM,Windows下是TerminateProcess),强制子进程退出;后续的p.join()可以确保子进程完全结束后再退出主进程。
注:子进程中的KeyboardInterrupt捕获逻辑在这个场景下其实不会被触发,因为子进程不会收到主进程的Ctrl+C信号。如果需要更优雅的退出方式,也可以使用multiprocessing.Event来传递退出信号,但对于简单场景,terminate()已经足够高效。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

