首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用多进程Pool.map()时无法pickle <type 'instancemethod'>

使用多进程Pool.map()时无法pickle <type 'instancemethod'>
EN

Stack Overflow用户
提问于 2009-11-30 06:08:36
回答 12查看 143.9K关注 0票数 228

我正在尝试使用multiprocessingPool.map()函数来同时划分工作。当我使用以下代码时,它工作得很好:

代码语言:javascript
运行
复制
import multiprocessing

def f(x):
    return x*x

def go():
    pool = multiprocessing.Pool(processes=4)        
    print pool.map(f, range(10))


if __name__== '__main__' :
    go()

但是,当我在更面向对象的方法中使用它时,它就不起作用了。它给出的错误消息是:

代码语言:javascript
运行
复制
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup
__builtin__.instancemethod failed

当下面是我的主程序时,就会发生这种情况:

代码语言:javascript
运行
复制
import someClass

if __name__== '__main__' :
    sc = someClass.someClass()
    sc.go()

下面是我的someClass类:

代码语言:javascript
运行
复制
import multiprocessing

class someClass(object):
    def __init__(self):
        pass

    def f(self, x):
        return x*x

    def go(self):
        pool = multiprocessing.Pool(processes=4)       
        print pool.map(self.f, range(10))

有谁知道这个问题是什么,或者是一个简单的解决方法?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2009-11-30 06:16:15

问题是多进程必须要在进程间进行访问,而绑定的方法是不可访问的。解决方法(无论您是否认为它“容易”;-)是将基础结构添加到您的程序中,以允许对此类方法进行酸洗,并将其注册到copy_reg标准库方法中。

例如,Steven Bethard对this thread的贡献(接近线程的末尾)展示了一种完全可行的方法,它允许通过copy_reg进行方法酸化/取消酸化。

票数 127
EN

Stack Overflow用户

发布于 2014-01-25 09:11:46

所有这些解决方案都很丑陋,因为除非您跳出标准库,否则多处理和酸洗都会受到破坏和限制。

如果您使用一个名为pathos.multiprocesssingmultiprocessing分支,则可以直接在多处理的map函数中使用类和类方法。这是因为使用了dill而不是picklecPickle,而且dill几乎可以序列化python中的任何内容。

pathos.multiprocessing还提供了异步映射函数…它还可以使用多个参数(例如map(math.pow, [1,2,3], [4,5,6])) map函数

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

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

代码语言:javascript
运行
复制
>>> import pathos.pools as pp
>>> p = pp.ProcessPool(4)
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> x = [0,1,2,3]
>>> y = [4,5,6,7]
>>> 
>>> p.map(add, x, y)
[4, 6, 8, 10]
>>> 
>>> class Test(object):
...   def plus(self, x, y): 
...     return x+y
... 
>>> t = Test()
>>> 
>>> p.map(Test.plus, [t]*4, x, y)
[4, 6, 8, 10]
>>> 
>>> p.map(t.plus, x, y)
[4, 6, 8, 10]

明确地说,你可以在第一时间做你想做的事情,如果你想做的话,你可以从解释器做。

代码语言:javascript
运行
复制
>>> import pathos.pools as pp
>>> class someClass(object):
...   def __init__(self):
...     pass
...   def f(self, x):
...     return x*x
...   def go(self):
...     pool = pp.ProcessPool(4)
...     print pool.map(self.f, range(10))
... 
>>> sc = someClass()
>>> sc.go()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> 

从这里获取代码:https://github.com/uqfoundation/pathos

票数 77
EN

Stack Overflow用户

发布于 2011-08-08 04:40:36

您还可以在someClass()中定义一个__call__()方法,该方法调用someClass.go(),然后将someClass()的一个实例传递给池。这个对象是可拾取的,它工作得很好(对我来说)……

票数 36
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1816958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档