如何使用multiprocessing.Pool来处理无法pickle的函数

时间:2017-09-14 18:57:37

标签: python multiprocessing pickle

我想将一个函数用于多处理目的,但它不能被腌制。这是代码从根本上看起来的样子:

from multiprocessing import Pool

def g(x):
  def g1(y):
    return x*y
  return g1

if __name__ == "__main__":
    f=g(5)
    Pool(2).map(f,[2,3])

但是当我运行代码时,我得到错误:

File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
    raise self._value
cPickle.PicklingError: Can't pickle <type 'function'>: attribute lookup 
    __builtin__.function failed

我已经读过copy_reg可以解决问题,但这些例子让我很困惑。此外,其中一些使用其他包,如marshal。如果可能,有人可以使用copy_reg提供一个简单的解决方案吗?

1 个答案:

答案 0 :(得分:1)

您不能将copy_reg用于此目的。 copy_reg.pickle()接受一个类型,一个函数作为参数,然后它使用该函数来pickle那种类型的对象。换句话说,它可以用于定义用于从给定类创建的酸洗对象的函数。以下是文档中的示例:

>>> import copy_reg, copy, pickle
>>> class C(object):
...     def __init__(self, a):
...         self.a = a
...
>>> def pickle_c(c):
...     print("pickling a C instance...")
...     return C, (c.a,)
...
>>> copy_reg.pickle(C, pickle_c)
>>> c = C(1)
>>> d = copy.copy(c)
pickling a C instance...
>>> p = pickle.dumps(c)
pickling a C instance...

然而,不要害怕。您尝试解决的问题已经有了解决方案。有一个名为pathos的库,它包含一个名为ProcessingPool的类,它可以完全满足您的需求。您只需要在命令行中键入:

pip install -U pathos

您现在可以使用pathos而不是mulitprocessing.Pool

from pathos.multiprocessing import ProcessingPool

def g(x):
    return lambda y: print(x*y)

if __name__ == '__main__':
    f = g(5)
    ProcessingPool(2).map(f, [2, 3])