多个进程之间共享list、dict等类型,可以使用multiprocessing模块里的Manager方法,由Manager()返回的管理器对象控制着一个服务器进程,该进程持有Python对象,并允许其他进程使用代理对其进行操作,管理器对象支持的类型有list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Queue, Value and Array
共享列表和字典示例代码:
from multiprocessing import Process, Manager
def f(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.reverse()
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list(range(10))
p = Process(target=f, args=(d, l))
p.start()
p.join()
print(d)
print(l)
输出:
{0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
注意,如果想要使用嵌套的列表和字典,嵌套的列表和字典必须都使用Manager.list和Manager.dict返回的对象,否则内层的列表和变量不会被修改。如下是错误代码:
from multiprocessing import Process, Manager
def f(d):
d['numbers'].reverse()
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
d['numbers']=list(range(10))
p = Process(target=f, args=(d,))
p.start()
p.join()
print(d)
输出
{'numbers': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
可以看到数据并没有改变,正确写法如下:
from multiprocessing import Process, Manager
def f(d):
d['numbers'].reverse()
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
d['numbers']=manager.list(range(10))
p = Process(target=f, args=(d,))
p.start()
p.join()
print(d)
print(d['numbers'])
输出如下:
{'numbers': <ListProxy object, typeid 'list' at 0x256d569f160>}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
结果正确。
参考:
1.https://docs.python.org/3.7/library/multiprocessing.html#sharing-state-between-processes