Python多处理PicklingError:无法pickle
我不能用一个简单的例子再现这个错误,而且我的代码太复杂了,无法发布。如果我用I Python shell
而不是普通的Python来运行程序,事情会很顺利。
我查阅了以前关于这个问题的一些笔记。它们都是由使用池调用类函数中定义的函数引起的。但对我来说不是这样。
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 313, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
我很感激你的帮助。
更新:函数I pickle
是在模块的顶层定义的。尽管它调用包含嵌套函数的函数。i、 e,f()
调用g()
调用h()
,h(
)有一个嵌套函数i()
,我正在调用pool.apply_async(f)
。f()
、g()
、h(
)都是在顶层定义的。我用这个模式尝试了一个更简单的例子,但还是成功了。
-
这是一份可以腌制的东西的清单。特别是,函数只有在模块的顶层定义时才是可选择的。
这段代码:import multiprocessing as mp class Foo(): @staticmethod def work(self): pass if __name__ == '__main__': pool = mp.Pool() foo = Foo() pool.apply_async(foo.work) pool.close() pool.join()
产生的错误几乎与你发布的错误相同:
Exception in thread Thread-2: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py", line 505, in run self.__target(*self.__args, **self.__kwargs) File "/usr/lib/python2.7/multiprocessing/pool.py", line 315, in _handle_tasks put(task) PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
问题在于,
pool
所有方法都使用a mp.SimpleQueue
将任务传递给工作进程。mp.SimpleQueue
必须经过的所有内容都必须是可选取的,并且foo.work不可选取,因为它不是在模块的顶层定义的。可以通过在顶层定义一个函数来修复该问题,该函数调用
foo.work()
:def work(foo): foo.work() pool.apply_async(work,args=(foo,))
请注意,它foo是可拾取的,因为它Foo是在顶层定义的并且
foo.__dict__
是可拾取的。