将接受类成员函数作为变量的函数传递给python multiprocess pool.map()

时间:2013-01-22 17:40:28

标签: python multiprocessing

嗨,我在早上的大部分时间里一直在努力解决这个问题,希望有人能指出我正确的方向。

这是我目前的代码:

def f(tup):
    return some_complex_function(*tup)

def main():

    pool = Pool(processes=4) 
    #import and process data omitted 
    _args = [(x.some_func1, .05, x.some_func2) for x in list_of_some_class]
    results = pool.map(f, _args)
    print results

我得到的第一个错误是:

> Exception in thread Thread-2: Traceback (most recent call last):  
> File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
>     self.run()   File "/usr/lib/python2.7/threading.py", line 504, in run
>     self.__target(*self.__args, **self.__kwargs)   File "/usr/lib/python2.7/multiprocessing/pool.py", line 319, in
> _handle_tasks
>     put(task) PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:9)

multiprocess模块使用pickle模块序列化传递给函数(f)的参数,该函数在另一个进程中执行。

许多内置类型都可以进行pickle,但实例方法无法进行pickle。所以.05很好,但x.some_func1不是。有关详细信息,请参阅What can be pickled and unpickled?

没有简单的解决方案。您需要重新构建程序,因此不需要将实例方法作为参数传递(或避免使用multiprocess)。

答案 1 :(得分:3)

如果使用名为multiprocessing的{​​{1}}的分支,则可以在多处理的pathos.multiprocesssing函数中直接使用类和类方法。这是因为map代替dillpickle,而cPickle可以在python中序列化几乎所有内容。

dill还提供异步映射函数......它可以pathos.multiprocessing具有多个参数的函数(例如map

请参阅: What can multiprocessing and dill do together?

和: http://matthewrocklin.com/blog/work/2013/12/05/Parallelism-and-Serialization/

map(math.pow, [1,2,3], [4,5,6])

在此处获取代码:  https://github.com/uqfoundation/pathos