无法将项目附加到多处理共享列表
Cannot append items to multiprocessing shared list
我正在使用多处理为我的应用程序创建子进程。
我还共享了一个进程和子进程之间的字典。
我的代码示例:
主要流程:
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': []}
可能是什么问题?
谢谢
Manager.dict
会给你一个字典,其中直接更改将在进程之间传播,但它不会检测你是否更改了字典中包含的对象(比如存储在 "list_item"
下的列表) ).请参阅 SyncManager documentation 底部的注释:
Note: Modifications to mutable values or items in dict and list proxies will not be propagated through the manager, because the proxy has no way of knowing when its values or items are modified. To modify such an item, you can re-assign the modified object to the container proxy.
因此在您的示例中,当您在字典中设置列表时,列表会同步,但追加不会触发另一次同步。
您可以通过重新分配字典中的键来解决这个问题:
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
创建共享列表(尽管如果列表的元素是可变的,您仍然会遇到同样的问题——您需要在列表中重置它们以发送它们在进程之间)。
我正在使用多处理为我的应用程序创建子进程。 我还共享了一个进程和子进程之间的字典。
我的代码示例:
主要流程:
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': []}
可能是什么问题? 谢谢
Manager.dict
会给你一个字典,其中直接更改将在进程之间传播,但它不会检测你是否更改了字典中包含的对象(比如存储在 "list_item"
下的列表) ).请参阅 SyncManager documentation 底部的注释:
Note: Modifications to mutable values or items in dict and list proxies will not be propagated through the manager, because the proxy has no way of knowing when its values or items are modified. To modify such an item, you can re-assign the modified object to the container proxy.
因此在您的示例中,当您在字典中设置列表时,列表会同步,但追加不会触发另一次同步。
您可以通过重新分配字典中的键来解决这个问题:
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
创建共享列表(尽管如果列表的元素是可变的,您仍然会遇到同样的问题——您需要在列表中重置它们以发送它们在进程之间)。