当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
语句。