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

2024-09-30 22:28:26 发布

您现在位置:Python中文网/ 问答频道 /正文

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

编辑:显然,我在这里试图实现的是将数据(列表)中的项目附加到dict列表中。数据项在目录中给出索引

预期产出{'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)```

Tags: 方法infromtree列表fordatadef
1条回答
网友
1楼 · 发布于 2024-09-30 22:28:26

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

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

相关问题 更多 >