Watch at Ease看见世界,读懂生活。

科技 · 实用指南

Python 报 BrokenProcessPool?重建进程池前先保全 worker 退出边界

该异常只证明 worker 非正常结束。先保存任务、PID、启动方式、stderr、退出状态与 OOM 证据,再决定修复导入、崩溃、容量还是部署。

原创图示:BrokenProcessPool 的任务到 worker 退出证据链。
原创示意图:重建进程池前保全第一条退出边界。 Watch at Ease

BrokenProcessPool 并不等于 OOM,也不等于 __main__ 一定写错;它只表示 ProcessPoolExecutor 的 worker 没有干净退出。自动重试可能抹掉唯一的第一现场。

把一次失败绑定到任务、worker 和系统事件,按证据分类后只修一个已证明的边界,再用同一任务和第二个普通任务验收。

1. 重建进程池前冻结一次失败

记录任务 ID、安全的输入指纹、提交时间、Python 版本、平台、执行器参数与启动方式,保存完整异常链。

不要先写无限重试;先在相同模块、initializer、启动方式与资源上限下缩成一个失败任务。

2. 区分入口失败与进程死亡

验证保存的 __main__ 可导入,创建进程的代码已保护,函数、参数与返回值可序列化;用同一启动方式跑一个顶层小函数。

小任务都未启动时修入口、pickle 或 initializer;真实任务启动后才破池时,继续取退出证据。

3. 捕获 worker 退出边界

为任务写入 ID,并把 PID、initializer 完成、任务开始、stderr 与 faulthandler 输出保存到进程池销毁后仍存在的位置。

不要把私有 executor 属性当长期接口;按 Python 版本记录可获得的退出码或信号,并保留宿主崩溃日志。

4. 关联信号、OOM 与部署事件

Linux 上比较运行前后的 memory.events;只有与该工作负载和时间窗一致的 oom_kill 增量才证明 OOM。

把峰值内存、并发、输入大小、服务重启和运维终止事件放进同一时间线;无证据就保持未决。

5. 只修已证明的类别并双重验收

入口问题修模块或序列化;原生崩溃修扩展;OOM 调整输入、并发或已测上限;外部终止修监督器或部署策略。

用相同条件重跑原失败任务,再让同一进程池执行第二个普通任务;两者通过且无新增崩溃或 OOM 事件才验收。

原创图示:按导入、信号与 OOM 证据分类的修复矩阵。
原创示意图:不同退出证据必须对应不同修复与验收。 Watch at Ease