谁能解释为什么下面的代码会产生密钥错误?多处理器命名空间管理器的字典是否有问题?
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)
如果在更新操作后添加打印,您将看到更新没有任何效果:
def f(string, namespace):
namespace.results_dict[string] = string
print(namespace)
指纹:
Namespace(results_dict={})
这是因为每次访问namespace.results_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)
现在,对该字典的更改将立即可见,但对命名空间中其他可变数据结构的更改仍将仅在写入访问时更新。
不确定这是否是预期的,或者命名空间的行为是否像您期望的那样。一个简单的解决方法是从管理器对象创建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
对象分配给命名空间属性也应该有效。