主进程先建好连接池再 fork 出四个子进程,子进程第一次查库就停在那里不返回,等满三十秒超时,父进程自己查却是正常的。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
from multiprocessing import get_context
ctx = get_context('spawn')
p = ctx.Process(target=worker)
p.start()
p.join()
fork 只复制内存页,socket 和锁的状态被一起继承,多个进程共用同一个连接句柄,请求和响应互相串,SSL 会话也对不上,只能卡住等超时。这一点先确认清楚,后面就不用反复试。
碰到「fork 继承连接」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
具体做法是,连接池在 fork 之后、每个子进程内部各自创建,别在父进程里先建好;用 spawn 启动方式从源头避开句柄继承,代价是启动稍慢一些;父进程 fork 前把已有连接池显式关闭,让子进程重新建立。
改完照着核一遍,子进程查询能正常返回,不再出现固定三十秒的超时,日志里也没有异常。
