进程间通信(IPC InterProcess Communication)是值在不同进程间传播或交换信息。
IPC通过有管道(无名管道 和 有名 / 命名管道)、消息队列、共享存储 / 内容、信号量、套接字socket、streams,其中socket和streams支持不同主机上的两个进程间通信
1 管道Pipe的基本语法
管道Pipe是multiprocessing中的方法Pipe(),也即multiprocessing.Pipe()
multiprocessing.Pipe([duplex])
功能:创建管道对象
参数:可选参数,
如果不设置参数,表示默认True,此时为全双工通信;
如果设置为False,则表示单向通信,也即一个返回值只能接受,第二个返回值只能发送
返回值:返回两个值,表示管道的两端,一端调用send发送消息,一端调用recv接受消息
注意:管道必须有发送端和接受端,不能只有单端;
无发送端,有接受端,会阻塞在recv,程序无法结束
有发送端,无接受端,程序可以结束,但没有msg消息
特点:
1)半双工(即数据只能在一个方向上流动)时具有固定的读端和写端。
2)只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
3)它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
2 应用实例
from multiprocessing import Process,Pipe import time import os child,parent = Pipe()#默认为True,全双工,false时为单向通信 def fun(name): time.sleep(1) child.send('hello' + str(name))#将send中的内容发送出去 # parent.send('hello' + str(name))#将child位置变换一下,双工条件下依然正常运行 print(os.getppid(),"--------",os.getpid()) return jobs = [] for i in range(5): p = Process(target= fun, args=(i,)) jobs.append(p) p.start() for n in range(5): print(parent.recv())#用于接受send发送的mag # print(child.recv())#将parent位置变换一下,双工条件下依然正常运行 for j in jobs: j.join()#[1,2,3,4,5]在这些编号中如果1号进程没结束,2号进程也没结束,首先内核先记录2号,阻塞1号,待1号结束后,再执行2号,但是这些编号中没有先后顺序
运行
2809 ------ 2810 hello0 2809 ------ 2811 2809 ------ 2812 hello1 hello2 2809 ------ 2814 hello4 2809 ------ 2813 hello3 ***********************
注意:5个进程执行时没有时间顺序
实例2
import multiprocessing import time def proc1(pipe): while True: for i in range(10000): print("send: %s" %(i)) pipe.send(i) time.sleep(1) def proc2(pipe): while True: print("proc2 rev:", pipe.recv()) time.sleep(1) def proc3(pipe): while True: print("proc3 rev:", pipe.recv()) time.sleep(1) if __name__ == "__main__": pipe = multiprocessing.Pipe() p1 = multiprocessing.Process(target=proc1, args=(pipe[0],)) p2 = multiprocessing.Process(target=proc2, args=(pipe[1],)) #p3 = multiprocessing.Process(target=proc3, args=(pipe[1],)) p1.start() p2.start() #p3.start() p1.join() p2.join() #p3.join()
运行
send: 0 proc2 rev: 0 send: 1 proc2 rev: 1 send: 2 proc2 rev: 2 send: 3 proc2 rev: 3 send: 4 proc2 rev: 4 ...
实例2参考: