Windows 11下Multiprocessing Pool停止运行问题排查与解决
多进程池中断后资源耗尽导致任务无法启动的问题
问题场景
原代码启动5个multiprocessing任务,每个任务循环10次打印消息并随机休眠1-5秒,整套任务最长约50秒完成。创建进程池时会打印池对象地址。
出现的异常情况:
- 中途通过键盘中断(Ctrl+C)终止程序后,再次运行会分配新的池对象地址;
- 多次中断后,代码彻底失效:任务无法创建,直接执行到结束,池对象重复分配同一地址;
- 关闭命令提示符窗口后资源仍未释放,新开窗口运行程序依旧无法启动任务,直接跳过
pool.join(); - 仅重启操作系统能释放资源,调试时因无法完整执行到
pool.close()和pool.join(),几次调试后就无法分配新任务。
原代码如下:
import multiprocessing import time import random # Simultaneous tasks running def task(id): for i in range(10): stime = random.randint(1,5) print(f"Task {id}: Woke up. Now sleep {stime}") time.sleep(stime) exit(0) if __name__ == "__main__": print ('create pool of tasks') pool = multiprocessing.Pool(processes=5) print (pool) # Start 5 asynchronous tasks for i in range(1,6): result = pool.apply_async(task, i) print (result) pool.close() # Wait for all tasks to complete pool.join() print ('end program')
解决方案
要确保衍生进程被终止且资源归还,需要在代码中处理中断信号、主动清理资源,具体做法如下:
捕获键盘中断信号,强制终止进程池
在主进程中捕获KeyboardInterrupt异常,调用pool.terminate()强制终止所有子进程,再执行pool.join()等待资源回收。这一步能确保即使中途中断,也能主动清理子进程,避免资源泄漏。使用上下文管理器(
with语句)管理进程池multiprocessing.Pool支持上下文管理器,会自动在代码块结束时调用close()和join(),即使发生异常也能自动清理资源,简化资源管理逻辑。修复
apply_async的参数传递问题
原代码中pool.apply_async(task, i)的参数传递错误,apply_async的第二个参数需要是元组,正确写法应为pool.apply_async(task, (i,)),否则会导致参数解析错误,这也是可能引发异常的潜在问题。
修改后的完整代码:
import multiprocessing import time import random def task(id): for i in range(10): stime = random.randint(1,5) print(f"Task {id}: Woke up. Now sleep {stime}") time.sleep(stime) if __name__ == "__main__": print('create pool of tasks') # 使用上下文管理器自动管理池的生命周期 with multiprocessing.Pool(processes=5) as pool: print(pool) # 修复参数传递为元组格式 for i in range(1,6): result = pool.apply_async(task, (i,)) print(result) try: # 等待所有任务完成,捕获键盘中断 pool.close() pool.join() except KeyboardInterrupt: print("\n收到中断信号,正在终止所有子进程...") pool.terminate() pool.join() print('end program')
- 手动清理残留进程(应急方案)
如果已经出现资源耗尽的情况,无需重启系统,可以通过系统工具手动杀死残留的Python子进程:- Windows:打开任务管理器,找到所有
python.exe或pythonw.exe进程,结束掉无关的进程; - Linux/macOS:在终端执行
ps aux | grep python找到残留进程,用kill -9 <进程ID>强制终止。
- Windows:打开任务管理器,找到所有
内容的提问来源于stack exchange,提问作者Jay Mosk
相关产品推荐
相关产品推荐

