关于具有字典键的多处理管理器的困惑

时间:2018-01-19 09:14:56

标签: python dictionary multiprocessing

任何人都可以解释为什么以下代码会产生密钥错误吗?多处理器命名空间管理器是否存在字典问题?

import multiprocessing

def f(string, namespace):
    namespace.results_dict[string] = string

if __name__ == '__main__':
    mgr = multiprocessing.Manager()
    ns = mgr.Namespace()
    ns.results_dict = {}
    p = multiprocessing.Process(target=f, args=('burger', ns,))

    p.start()
    p.join()

    print(ns.results_dict)

2 个答案:

答案 0 :(得分:3)

如果您在更新操作后添加打印件,您将看到更新没有任何效果:

def f(string, namespace):
    namespace.results_dict[string] = string
    print(namespace)

打印:

Namespace(results_dict={})

这是因为每次访问namespace.results_dict时,都会从托管命名空间中检索其值(空字典)。该dict的状态不受管理,只能直接访问命名空间。 要使您的示例正常工作,您必须使用更改的dict显式更新名称空间,例如:

def f(string, namespace):
    r = namespace.results_dict   # retrieves copy
    r[string] = string           # modify local copy
    namespace.results_dict = r   # write it back

您也可以使用原始函数results_dict作为if __name__ == '__main__': mgr = multiprocessing.Manager() ns = mgr.Namespace() ns.results_dict = mgr.dict() p = multiprocessing.Process(target=f, args=('burger', ns,)) p.start() p.join() print(ns.results_dict) 使用托管字典:

jobFinished(parameters, false);

现在对该字典的更改将立即可见,但对命名空间中其他可变数据结构的更改仍将仅在写访问时更新。

答案 1 :(得分:2)

不确定这是否是预期的,或者命名空间的行为与您预期的行为一样。这里一个简单的解决方法是从管理器对象

创建dict()
import multiprocessing

def f(string, result_dict):
    result_dict[string] = string

if __name__ == '__main__':
    mgr = multiprocessing.Manager()
    ns = mgr.dict()
    p = multiprocessing.Process(target=f, args=('burger', ns,))

    p.start()
    p.join()

    print(ns)

我得到了

{'burger': 'burger'}

将此Manager.dict对象分配给您的命名空间属性也应该有效。