科技 · 实用指南
Python 报 BrokenProcessPool?重建进程池前先保全 worker 退出边界
该异常只证明 worker 非正常结束。先保存任务、PID、启动方式、stderr、退出状态与 OOM 证据,再决定修复导入、崩溃、容量还是部署。

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 事件才验收。
