python - 在 Python multiprocessing.Pool 中共享可变全局变量

标签 python python-3.x multiprocessing python-multiprocessing multiprocessing-manager

我正在尝试使用以下代码更新共享对象(dict)。但这不起作用。它为我提供了输入 dict 作为输出。

编辑:Exxentially,我在这里想要实现的是将数据(列表)中的项目附加到字典的列表中。数据项给出字典中的索引。

预期输出:{'2': [2], '1': [1, 4, 6], '3': [3, 5]}
注意:方法 2 引发错误 TypeError: 'int' object is not iterable

  1. 方法 1

    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)])
    
  2. 方法 2
 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)```

最佳答案

如果您希望反射(reflect)更改,则需要使用托管列表。因此,以下内容对我有用:

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()})

关于python - 在 Python multiprocessing.Pool 中共享可变全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61518970/

相关文章:

python - 在脚本中转置矩阵时出现索引错误

python - 如何在 python 中使用 lxml 去除 xml 标签中的所有子标签,但保留文本合并到 parens?

c++ - 导入到 Python 3 时 Boost.Python 和 C++ 编译库错误

Python子进程SSH关闭连接

python - dict可以在父进程和子进程之间共享吗?

python - Python 中的并行程序不产生输出

python - 如何使用 docker Docker SDK for Python 获取容器大小

python - 我无法设置顶级标题

Python正则表达式查找特殊字符和中间的字符

python - 多处理 - 无法将列表写入 csv(TypeError : 'ApplyResult' object is not iterable)