Python multiprocessing: set() in dict() 不起作用



当dict((中有set((时,.add((函数不起作用。

manager = multiprocessing.Manager()
shared_dict = manager.dict()
def worker1(d, key):
if key not in shared_dict:
d[key] = {'0': set(), '1': set()}
def worker2(d, key):
if key not in shared_dict:
d[key] = {'0': set(), '1': set()}
d[key]['0'].add(1)
d[key]['1'].add(2)

process1 = multiprocessing.Process(
target=worker1, args=[shared_dict, 'a'])
process2 = multiprocessing.Process(
target=worker2, args=[shared_dict, 'b'])
process1.start()
process2.start()
process1.join()
process2.join()

我期望以下输出:

{'a': {'1': set([]), '0': set([])}, 'b': {'1': (2), '0': (1)}}

而不是:

{'a': {'1': set([]), '0': set([])}, 'b': {'1': set([]), '0': set([])}}

你可以在Python文档中阅读你的问题,其中说:

如果标准(非代理(列表或字典对象包含在 参照,对这些可变值的修改将不会传播 通过管理器,因为代理无法知道何时 修改 中包含的值。

因此,在"正常"情况下,如果您创建对对象的新引用并对其进行修改,则无论您使用哪个引用来修改它,修改都会应用于该对象:

a = set([1])
b = a
b.add(2)
print(a, b)    # {1, 2} {1, 2}

但是,在管理器中,由于引用的原因,修改不会应用于对象。不过,您可以创建对对象的新引用,在那里更改值形式,然后将修改后的版本重新分配给字典。

import multiprocessing
manager = multiprocessing.Manager()
shared_dict = manager.dict()
def worker1(d, key):
d.setdefault(key, {'0': set(), '1': set()})
def worker2(d, key):
d.setdefault(key, {'0': set(), '1': set()})

buffer = d[key]
for i, (k, v) in enumerate(buffer.items()):
buffer[k].add(i)
d[key] = buffer

process1 = multiprocessing.Process(
target=worker1, args=[shared_dict, 'a'])
process2 = multiprocessing.Process(
target=worker2, args=[shared_dict, 'b'])

process1.start()
process2.start()
process1.join()
process2.join()

顺便说一句,使用dict.setdefault重构这些if语句。

相关内容

  • 没有找到相关文章

最新更新