多個進程之間共享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