python - 在 Python multiprocessing.Pool 中共享可变全局变量
问题描述
我正在尝试dict
使用以下代码更新共享对象 (a)。但它不起作用。它给了我输入dict
作为输出。
编辑:Exxentially,我在这里想要实现的是将数据(列表)中的项目附加到字典的列表中。数据项在字典中给出索引。
预期输出:{'2': [2], '1': [1, 4, 6], '3': [3, 5]}
注意:方法 2 引发错误TypeError: 'int' object is not iterable
方法一
from multiprocessing import * def mapTo(d,tree): for idx, item in enumerate(list(d), start=1): tree[str(item)].append(idx) data=[1,2,3,1,3,1] manager = Manager() sharedtree= manager.dict({"1":[],"2":[],"3":[]}) with Pool(processes=3) as pool: pool.starmap(mapTo, [(data,sharedtree ) for _ in range(3)])
- 方法二
from multiprocessing import *
def mapTo(d):
global tree
for idx, item in enumerate(list(d), start=1):
tree[str(item)].append(idx)
def initializer():
global tree
tree = dict({"1":[],"2":[],"3":[]})
data=[1,2,3,1,3,1]
with Pool(processes=3, initializer=initializer, initargs=()) as pool:
pool.map(mapTo,data)```
解决方案
如果要反映更改,则需要使用托管列表。所以,以下对我有用:
from multiprocessing import *
def mapTo(d,tree):
for idx, item in enumerate(list(d), start=1):
tree[str(item)].append(idx)
if __name__ == '__main__':
data=[1,2,3,1,3,1]
with Pool(processes=3) as pool:
manager = Manager()
sharedtree= manager.dict({"1":manager.list(), "2":manager.list(),"3":manager.list()})
pool.starmap(mapTo, [(data,sharedtree ) for _ in range(3)])
print({k:list(v) for k,v in sharedtree.items()})
这是输出:
{'1': [1, 1, 1, 4, 4, 4, 6, 6, 6], '2': [2, 2, 2], '3': [3, 3, 5, 3, 5, 5]}
请注意,在使用多处理时,您应该始终使用if __name__ == '__main__':
防护,另外,避免加星标的导入......
编辑
如果您在 Python < 3.6 上,则必须重新分配,因此将其用于mapTo
:
def mapTo(d,tree):
for idx, item in enumerate(list(d), start=1):
l = tree[str(item)]
l.append(idx)
tree[str(item)] = l
最后,您没有正确使用starmap
/ map
,您将数据传递了三次,所以当然,所有内容都被计算了三次。映射操作应该适用于您要映射的数据的每个单独元素,因此您需要以下内容:
from functools import partial
from multiprocessing import *
def mapTo(i_d,tree):
idx,item = i_d
l = tree[str(item)]
l.append(idx)
tree[str(item)] = l
if __name__ == '__main__':
data=[1,2,3,1,3,1]
with Pool(processes=3) as pool:
manager = Manager()
sharedtree= manager.dict({"1":manager.list(), "2":manager.list(),"3":manager.list()})
pool.map(partial(mapTo, tree=sharedtree), list(enumerate(data, start=1)))
print({k:list(v) for k,v in sharedtree.items()})
推荐阅读
- kubernetes - 如何查看 VS 2019 YAML 模板输出生成
- django - 从 shell 脚本运行测试时,Apache jena-fuseki 服务器拒绝连接
- excel - VBA 公式 R1C1 不接受方括号内的计算
- ruby-on-rails - 在 has_many 关系中进行分配是在数据库中进行更新
- python - 如何从列表中提取特征?
- flutter - Flutter:在最终构建时忽略文件夹
- sql-server - 报表查看器中的存储过程
- cypress - 我们希望在父窗口中找到全局赛普拉斯,但它不见了!柏树中的错误
- azure - 如果 Azure AKS 群集没有区域感知,这意味着什么?
- java - idea maven 无法重新连接