from multiprocessing import Pool, Manager
def task(args):
k, v, sharedDict, lock = args
with lock:
if k not in sharedDict:
sharedDict[k] = {}
sharedDict[k]['current'] = v
print(f"sharedDict[k]['current'] = {sharedDict[k]['current']}")
def main():
manager = Manager()
lock = manager.Lock()
dic = manager.dict()
pool = Pool(processes=2)
tasks = [('a', {'A': 1}, dic, lock), ('b', {'B': 2}, dic, lock), ('c', {'C': 3}, dic, lock), `your text`('d', {'D': 4}, dic, lock)]
pool.map(task, tasks)
pool.close()
pool.join()
if __name__ == '__main__':
main()
当我运行上面的代码时,这一行抛出一个错误:print(f"sharedDict[k]['current'] ={sharedDict[k]['current']}"),KeyError: 'current',即使我已经明确地将值添加到字典中。我希望有人能帮助我。
来自 Python 文档1,
如果标准(非代理)列表或字典对象包含在引用中,则对这些可变值的修改将不会通过管理器传播,因为代理无法知道其中包含的值何时被修改。然而,在容器代理中存储一个值(这会在代理对象上触发
)确实会通过管理器传播,因此为了有效地修改此类项目,可以将修改后的值重新分配给容器代理__setitem__
sharedDict[k] = {}
sharedDict[k]['current'] = v
print(f"sharedDict[k]['current'] = {sharedDict[k]['current']}")
sharedDict[k]
是 sharedDict
中的嵌套对象。它的更改不会被传播。解决方法是创建一个临时的本地字典。
def task(args):
k, v, shared_dict, lock = args
with lock:
if k not in shared_dict:
shared_dict[k] = {}
inner_dict = shared_dict[k]
inner_dict['current'] = v
shared_dict[k] = inner_dict
print(f"{shared_dict[k]['current']} = ")
行
shared_dict[k] = inner_dict
将调用 __setitem__
上的 sharedDict
,强制其更新。
感谢@ken