【发布时间】:2011-03-18 08:17:22
【问题描述】:
当我运行类似的东西时:
from multiprocessing import Pool
p = Pool(5)
def f(x):
return x*x
p.map(f, [1,2,3])
它工作正常。然而,把它作为一个类的函数:
class calculate(object):
def run(self):
def f(x):
return x*x
p = Pool()
return p.map(f, [1,2,3])
cl = calculate()
print cl.run()
给我以下错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/sw/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/sw/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "/sw/lib/python2.6/multiprocessing/pool.py", line 225, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
我看过 Alex Martelli 的一篇帖子处理了同样的问题,但不够明确。
【问题讨论】:
-
“这是一个类的函数”?你能发布实际得到实际错误的代码吗?如果没有实际代码,我们只能猜测您做错了什么。
-
一般来说,存在比 Python 的标准 pickle 模块更强大的 pickling 模块(如 this answer 中提到的 picloud 模块)。
-
我在
IPython.Parallel中遇到了类似的闭包问题,但是您可以通过将对象推送到节点来解决这个问题。用多处理解决这个问题似乎很烦人。 -
这里
calculate是可腌制的,所以这似乎可以通过以下方式解决:1)使用复制calculate实例的构造函数创建一个函数对象,然后2)传递这个实例Pool的map方法的函数对象。没有? -
@math 我不相信 Python 的任何“最近的变化”会有任何帮助。
multiprocessing模块的一些限制是由于它的目标是跨平台实现,并且在 Windows 中缺少类似fork(2)的系统调用。如果您不关心 Win32 支持,可能有更简单的基于流程的解决方法。或者,如果您准备使用线程而不是进程,则可以将from multiprocessing import Pool替换为from multiprocessing.pool import ThreadPool as Pool。
标签: python multiprocessing pickle