这是一份可以腌制的东西的清单。特别是,函数只有在模块的顶层定义时才是可选择的。 这段代码:
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__
是可拾取的。