我使用多处理为我的应用程序创建子流程。 我还在流程和子流程之间共享字典。
我的代码示例:
主要流程:
from multiprocessing import Process, Manager
manager = Manager()
shared_dict = manager.dict()
p = Process(target=mysubprocess, args=(shared_dict,))
p.start()
p.join()
print shared_dict
我的子流程:
def mysubprocess(shared_dict):
shared_dict['list_item'] = list()
shared_dict['list_item'].append('test')
print shared_dict
在这两种情况下,印刷值为:
{'list_item': []}
可能是什么问题? 感谢
答案 0 :(得分:7)
Manager.dict
将为您提供一个直接更改将在进程之间传播的字典,但它不会检测您是否更改了dict中包含的对象(如"list_item"
下存储的列表)。请参阅SyncManager documentation:
注意:对dict和列表代理中的可变值或项目的修改不会通过管理器传播,因为代理无法知道其值或项目何时被修改。要修改此类项,可以将修改后的对象重新分配给容器代理。
因此,在您的示例中,当您在dict中设置列表时,列表会被同步,但附加内容不会触发另一个同步。
你可以通过在dict中重新分配密钥来解决这个问题:
from multiprocessing import Process, Manager
def mysubprocess(shared_dict):
item = shared_dict['list_item'] = list()
item.append('test')
shared_dict['list_item'] = item
print 'subprocess:', shared_dict
manager = Manager()
shared_dict = manager.dict()
p = Process(target=mysubprocess, args=(shared_dict,))
p.start()
p.join()
print 'main process:', shared_dict
但是如果列表增长很长,那可能会效率低下 - 整个列表将被序列化并发送到每个附加的管理器进程。在这种情况下,更好的方法是直接使用SyncManager.list
创建共享列表(尽管如果列表的元素是可变的,您仍会遇到同样的问题 - 您需要在列表中将它们重置为在进程之间发送它们。)