python - 使用多处理池时更新对象的成员变量
问题描述
我有一个B
由另一个类组成的类A
。
在课堂B
上,我使用多处理池从 class 调用方法A
。A
此方法更新(它是一个字典)的成员变量。
当我打印出这个成员变量时,它似乎没有被更新。这是描述该问题的代码:
import multiprocessing as mp
class A():
def __init__(self):
self.aDict = {'key': 0}
def set_lock(self, lock):
self.lock = lock
def do_work(self, item):
print("Doing work for item: {}".format(item) )
self.aDict['key'] += 1
return [1,2,3] # return some list
class B():
def __init__(self):
self.objA = A()
def run_with_mp(self):
items=['item1', 'item2']
with mp.Pool(processes=mp.cpu_count()) as pool:
result = pool.map_async(self.objA.do_work, items)
result.wait()
pool.terminate()
print(self.objA.aDict)
def run(self):
items=['item1', 'item2']
for item in items:
self.objA.do_work(item)
print(self.objA.aDict)
if __name__ == "__main__":
b = B()
b.run_with_mp() # prints {'key': 0}
b.run() # prints {'key': 2}
b.run_with_mp()
打印{'key': 0}
整个b.run()
打印件{'key': 2}
。我认为多处理池版本也会这样做,因为该对象具有多处理池运行self.objA
的整个类的范围。B
我认为池中的每个工作人员都会看到不同版本的self.objA
,这与主程序流程中的不同。有没有办法让所有工作人员更新一个公共变量?
解决方案
您接近解释,确实,每个生成的进程都有自己的内存区域,这意味着它们是独立的。当您运行do_work
每个进程时,都会更新其版本,aDict
因为该变量未共享。如果要共享变量,最简单的方法是使用 a Manager
,例如:
import multiprocessing as mp
class A():
def __init__(self):
self.aDict = mp.Manager().dict({'key': 0})
def set_lock(self, lock):
self.lock = lock
def do_work(self, item):
print("Doing work for item: {}".format(item) )
self.aDict['key'] += 1
return [1,2,3] # return some list
class B():
def __init__(self):
self.objA = A()
def run_with_mp(self):
items=['item1', 'item2']
with mp.Pool(processes=mp.cpu_count()) as pool:
result = pool.map_async(self.objA.do_work, items)
result.wait()
pool.terminate()
print(self.objA.aDict)
def run(self):
items=['item1', 'item2']
for item in items:
self.objA.do_work(item)
print(self.objA.aDict)
if __name__ == "__main__":
b = B()
b.run_with_mp() # prints {'key': 2}
b.run() # prints {'key': 4}
我修改了您的示例以共享aDict
变量,因此每个进程都会更新该属性(run_with_mp
和run
方法)。考虑在docs中阅读更多内容。
推荐阅读
- reactjs - 使用 react-hot-loader 时 Webpack HMR 不会重新加载
- php - 我对丹麦字母 ÆØÅ 有疑问
- reactjs - “提升状态”或将状态设置器分享给孩子是更好的做法吗?
- docker - Docker 为 VueJS 与 GitlabCI 构建不一致
- java - CodeJam 的嵌套深度 - 已解决提示,但需要连接字符串 - 程序在输出中返回“Case # :”
- javafx - JavaFX 窗口大小小于 SceneBuilder
- bitmap - GMS3 中对话图形的部署是否发生了变化?
- ruby-on-rails - 如何在 Ruby on Rails 中仅列出来自 s3 的对象键?
- ruby-on-rails - 没有路由匹配缺少必需的键:[:locale]
- android - Cannot create instance of class ViewModel while using MVVM