python-- 程序管道 Pipe、程序 Manager
阿新 • • 發佈:2021-08-09
程序管道 Pipe
管道之間通訊是不安全的
from multiprocessing import Pipe con1,con2 = Pipe()
管道是用於多程序之間通訊的一種方式。如果在單程序中使用管道,那麼就是con1收資料,就是con2發資料。如果是con1發資料,就是con2收資料如果在多程序中使用管道,那麼就必須是父程序使用con1收,子程序就必須使用con2發
父程序使用con1發,子程序就必須使用con2收
父程序使用con2收,子程序就必須使用con1發
父程序使用con2發,子程序就必須使用con1收
在管道中有一個著名的錯誤叫做EOFError。是指,父程序中如果關閉了傳送端,子程序還繼續接收資料,那麼就會引發EOFError。
from multiprocessing import Pipe, Process def func(con): con1, con2 = con con1.close() # 子程序使用con2和父程序通訊,所以 while 1: try: print(con2.recv()) # 當主程序的con1發資料時,子程序要死迴圈的去接收。 except EOFError: # 如果主程序的con1發完資料並關閉con1,子程序的con2繼續接收時,就會報錯,使用try的方式,獲取錯誤 con2.close() #獲取到錯誤,就是指子程序已經把管道中所有資料都接收完了,所以用這種方式去關閉管道 break if __name__ == '__main__': con1, con2 = Pipe() p = Process(target=func, args=((con1, con2),)) p.start() con2.close() # 在父程序中,使用con1去和子程序通訊,所以不需要con2,就提前關閉 for i in range(10): # 生產資料 con1.send(i) # 給子程序的con2傳送資料con1.close() # 生產完資料,關閉父程序這一端的管道
結果:
0
1
2
3
4
5
6
7
8
9
例
from multiprocessing import Process, Pipe def f(conn): conn.send([42, None, 'hello fromchild']) conn.send([42, None, 'hello fromchild2']) print("from parent:", conn.recv()) conn.close() if __name__ == '__main__': parent_conn, child_conn = Pipe() # 需要兩個引數接收 p = Process(target=f, args=(child_conn,)) p.start() print(parent_conn.recv()) print(parent_conn.recv()) parent_conn.send("范冰冰")
結果:
[42, None, 'hello fromchild'] [42, None, 'hello fromchild2'] from parent: 范冰冰
parent_conn, child_conn = Pipe()生成管道例項,相當於socket通訊,一頭在主程序,一頭在子程序,就可以實現程序之間的資料的傳遞
程序 Manager
Queue,Pipe只能實現程序之間資料的傳遞,Manager可以進行資料之間的共享from multiprocessing import Manager, Value m = Manager() num = m.dict({鍵: 值}) num = m.list([1, 2, 3])
例
from multiprocessing import Process, Manager def func(num): num[0] -= 1 # num[0] = 1 print('子程序中的num的值是', num) if __name__ == '__main__': m = Manager() num = m.list([1, 2, 3]) p = Process(target=func, args=(num,)) p.start() p.join() print('父程序中的num的值是', num)
結果:
子程序中的num的值是 [0, 2, 3]
父程序中的num的值是 [0, 2, 3]