You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>强制终止。

内容的提问来源于stack exchange,提问作者Jay Mosk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:33:27