Multiprocessing pool异步worker调用触发NotImplementedError问题咨询
问题根因
你遇到的报错:
NotImplementedError: pool objects cannot be passed between processes or pickled
根因如下:
- Python的
multiprocessing模块跨进程传递任务时,会对传入的函数和参数做序列化(pickle)处理。你传入的self.worker是实例绑定方法,序列化时会自动将整个Sandbox实例对象一同序列化。 - 你的
Sandbox实例包含self.pool属性,而进程池Pool对象本身不可被序列化,因此触发上述报错。 - 删除
res.get()后无输出的原因是:apply_async是异步非阻塞调用,主进程没有等待子进程执行任务就直接运行结束,子进程还没来得及执行print逻辑就被销毁。
修复方案
方案1:将worker改为静态方法(最简便)
静态方法不绑定实例,序列化时不需要传递整个Sandbox对象,自然不会涉及不可序列化的Pool属性,代码示例如下:
from multiprocessing import Pool class Sandbox: def __init__(self): self.pool = Pool(4) @staticmethod def worker(x): print(x) # 正常输出testing123 return f"处理完成: {x}" def run(self): res = self.pool.apply_async(self.worker, ("testing123",)) print(res.get()) self.pool.close() self.pool.join() sandbox = Sandbox() sandbox.run()
方案2:重写类的序列化逻辑(适用需要访问实例可序列化属性的场景)
如果你的worker逻辑需要访问实例的其他普通属性,可以重写__getstate__方法,序列化时主动排除不可序列化的pool属性:
from multiprocessing import Pool class Sandbox: def __init__(self): self.pool = Pool(4) self.common_param = "实例普通属性" # 可正常访问的可序列化属性 def worker(self, x): print(x) print(self.common_param) return f"处理完成: {x}" def __getstate__(self): # 复制实例属性字典,删除不可序列化的pool后再返回用于序列化 state = self.__dict__.copy() del state["pool"] return state def run(self): res = self.pool.apply_async(self.worker, ("testing123",)) print(res.get()) self.pool.close() self.pool.join() sandbox = Sandbox() sandbox.run()
内容的提问来源于stack exchange,提问作者Shai
相关产品推荐
相关产品推荐

