【问题标题】:How can I parallelize method calls on an array of objects?如何并行化对象数组上的方法调用?
【发布时间】:2011-06-23 14:13:07
【问题描述】:

我有一个由对象列表组成的模拟。我想在所有这些对象上并行调用一个方法,因为它们都不依赖于另一个,使用线程池。你不能腌制方法,所以我正在考虑使用具有副作用的包装函数来执行以下操作:

from multiprocessing import Pool

class subcl:
    def __init__(self):
        self.counter=1
        return
    def increment(self):
        self.counter+=1
        return

def wrapper(targ):
    targ.increment()
    return

class sim:
    def __init__(self):
        self.world=[subcl(),subcl(),subcl(),subcl()]
    def run(self):
        if __name__=='__main__':
            p=Pool()
            p.map(wrapper,self.world)

a=sim()
a.run()
print a.world[1].counter #should be 2

但是,函数调用不会对数组中的实际对象产生预期的副作用。有没有办法简单地使用线程池和映射来处理这个问题,还是我必须根据原始函数调用和元组/列表/字典来做所有事情(或者使用多处理或其他一些并行库进行更详细的处理)?

【问题讨论】:

    标签: python multiprocessing


    【解决方案1】:

    混淆的主要来源是multiprocessing 使用单独的进程而不是线程。这意味着子级对对象状态所做的任何更改都不会自动对父级可见。

    在您的示例中处理此问题的最简单方法是让 wrapper 返回新值,然后使用 Pool.map 的返回值:

    from multiprocessing import Pool
    
    class subcl:
        def __init__(self):
            self.counter=1
            return
        def increment(self):
            self.counter+=1
            return
    
    def wrapper(targ):
        targ.increment()
        return targ                                        # <<<<< change #1
    
    class sim:
        def __init__(self):
            self.world=[subcl(),subcl(),subcl(),subcl()]
        def run(self):
            if __name__=='__main__':
                p=Pool()
                self.world = p.map(wrapper,self.world)     # <<<<< change #2
    
    a=sim()
    a.run()
    print a.world[1].counter # now prints 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-12
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多