簡體   English   中英

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

[英]Sharing mutable global variable in Python multiprocessing.Pool

我正在嘗試使用以下代碼更新共享的 object (一個dict )。 但它不起作用。 它給了我作為 output 的輸入dict

編輯:Exxentially,我在這里想要實現的是將數據(列表)中的 append 項添加到字典列表中。 數據項在字典中給出索引。

預期 output : {'2': [2], '1': [1, 4, 6], '3': [3, 5]}
注意:方法 2 引發錯誤TypeError: 'int' object is not iterable

  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. 方法二
 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

最后,您map starmap您將數據傳遞了三次,所以當然,一切都被計算了三次。 映射操作應該適用於您要映射的數據的每個單獨元素,因此您需要以下內容:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM