我有一个由对象列表组成的模拟。我想并行调用所有这些对象的方法,因为它们都不依赖于另一个,使用线程池。你不能挑选一个方法,所以我想使用带副作用的包装函数来执行以下操作:
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
但是,函数调用对数组中的实际对象没有预期的副作用。有没有办法简单地使用线程池和映射来处理它,或者我是否必须在原始函数调用和元组/列表/ dicts方面做所有事情(或者使用多处理或其他并行库来更精细地处理)?
答案 0 :(得分: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