day10-进程之间数据通讯(Pipe,manager)
一、概述
之前我们讲述了进程之间的是通过进程中的Queue,来进行数据共享的,其实还有一种方式实现数据共享,那就是管道,pipe,以及数据共享manger。
二、数据通信
2.1、Pipe()函数
英文解释:The Pipe() function returns a pair of connection objects connected by a pipe which by default is duplex (two-way)。
中文解释:管道函数会返回由管道双方连接的一组连接对象,该管道默认是双向的(双向的)。
1 from multiprocessing import Process,Pipe 2 3 def f(conn): 4 conn.send([18,None,"hello"]) 5 conn.send(["niubi"]) 6 print(conn.recv()) 7 conn.close() 8 9 if __name__ == '__main__': 10 parent_conn,child_conn =Pipe() 11 p=Process(target=f,args=(child_conn,)) 12 p.start() 13 print(parent_conn.recv()) 14 print(parent_conn.recv()) 15 parent_conn.send("from your laozi") 16 p.join()
注意了:子进程如果向父进程发送两次,但是父进程接收三次,那么会一直卡在那边。
收、发次数要相等,
三、共享
1 import os 2 from multiprocessing import Manager,Process 3 4 def f(d,l): 5 d[os.getpid()]=os.getpid() #获取进程ID,为key ,进程ID为vaule 6 7 l.append(os.getpid()) #获取进程ID 添加到列表 8 print(l) 9 10 11 12 if __name__ == '__main__': 13 with Manager() as manager: #别名 14 d =manager.dict() #利用manager c创建一个可以共享的字典 15 16 l=manager.list(range(5))#同上,创建一个列表 17 p_list=[] 18 for i in range(10): 19 p =Process(target=f,args=(d,l)) #多进程 20 p.start() 21 p_list.append(p) 22 for res in p_list: 23 res.join() 24 25 print(d) 26 print(l)
输出结果 ,10个进程共同修改一个数据。
D:\51cto\venv\Scripts\python.exe "D:/51cto/day 10/manager.py"
[0, 1, 2, 3, 4, 8124]
[0, 1, 2, 3, 4, 8124, 5336]
[0, 1, 2, 3, 4, 8124, 5336, 5516]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376, 9528]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376, 9528, 9108]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376, 9528, 9108, 5236]
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376, 9528, 9108, 5236, 4924]
{8124: 8124, 5336: 5336, 5516: 5516, 8212: 8212, 6288: 6288, 4376: 4376, 9528: 9528, 9108: 9108, 5236: 5236, 4924: 4924}
[0, 1, 2, 3, 4, 8124, 5336, 5516, 8212, 6288, 4376, 9528, 9108, 5236, 4924]
Process finished with exit code 0
注意了:manger.dict()是用专门的语法生产一个可在多进程之间进行传递和共享的一个字典,就是dict(),这个时候生产的对象就是d。
疑问:这边要不要加锁呐?
答案:不用加锁,因为这个manger已经帮你加锁了,它就默认不允许两个进程同时修改一份数据。两个进程没有办法同时修改一份数据,进程之间是独立的,它自己也要加锁,因为它把自己的东西同时copy好几份,跟刚刚的那个Queue一样,copy10个字典最终合成一个字典。

浙公网安备 33010602011771号