Python多进程调用类方法:序列化及BaseProcess._Popen参数错误求助
Python多进程调用类方法的问题根源与规范实现
问题根源
1. 标准multiprocessing的cannot pickle '_io.TextIOWrapper' object错误
Python多进程间传递对象必须先序列化,标准库multiprocessing默认用pickle做序列化工具,但pickle无法处理部分特殊对象,比如打开的文件句柄(_io.TextIOWrapper)。你在主进程初始化的类实例里如果包含这类对象,当把实例传给子进程时,就会触发序列化失败的错误。
2. multiprocess库的TypeError: BaseProcess._Popen() takes 1 positional argument but 2 were given错误
multiprocess库是标准multiprocessing的扩展,用dill替代pickle支持更多对象序列化,但你错误地导入了内部基类BaseProcess当作Process使用。BaseProcess的_Popen方法参数设计和标准库的Process完全不同,直接按标准Process的方式传参,就会出现参数不匹配的报错。而multiprocess.Process是库封装好的、兼容标准库接口的类,用它才能正常启动子进程。
规范实现方式
方式一:使用标准multiprocessing(规避不可序列化对象)
如果要坚持用标准库,需确保类实例不含pickle无法序列化的对象,常见处理方式:
- 不在类实例中存储打开的文件句柄、网络连接等资源,改为在子进程方法内部按需创建/打开
- 若必须传递相关资源,只传路径、配置等可序列化的参数,让子进程自行初始化资源
示例代码:
import multiprocessing class MyClass: def __init__(self, file_path): # 仅存储文件路径,不存打开的文件对象 self.file_path = file_path def worker(self): # 子进程内打开文件并操作 with open(self.file_path, 'r') as f: print(f.readline()) if __name__ == '__main__': obj = MyClass('test.txt') p = multiprocessing.Process(target=obj.worker) p.start() p.join()
方式二:使用multiprocess库(支持更多序列化场景)
如果类实例必须包含pickle无法处理的对象,使用multiprocess库时必须导入正确的Process类,而非内部的BaseProcess:
示例代码:
import multiprocess class MyClass: def __init__(self): # 即使包含TextIOWrapper,dill也能完成序列化 self.f = open('test.txt', 'r') def worker(self): print(self.f.readline()) self.f.close() if __name__ == '__main__': obj = MyClass() # 必须使用multiprocess.Process,不能用BaseProcess p = multiprocess.Process(target=obj.worker) p.start() p.join()
注意:无论用哪种方式,都必须在if __name__ == '__main__':代码块中启动子进程,避免Windows系统下出现递归创建进程的问题(Python 3.11同样需要遵守该规则)。
内容的提问来源于stack exchange,提问作者hhharsha36
相关产品推荐
相关产品推荐

