在Python中,进程池中的多个进程在修改Manager模块生成的共享变量时遇到错误

问题描述 投票:0回答:1
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 process multiprocessing locking shared-variable
1个回答
0
投票

来自 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

© www.soinside.com 2019 - 2024. All rights reserved.