管道是进程通信之间最简单的方式。
参考资料
简介
pipe
是进程间通信最简单的方式,功能也比较单一。
管道只能连接两个进程,一个进程发送,另一个进程接受,由于功能简单,pipe
因此也是进程间通信最快的方式。
Pipe实现进程间通信
Pipe
直译过来的意思是“管”或“管道”,该种实现多进程编程的方式,和实际生活中的管(管道)是非常类似的。通常情况下,管道有 2
个口,而 Pipe
也常用来实现 2
个进程之间的通信,这 2
个进程分别位于管道的两端,一端用来发送数据,另一端用来接收数据。
使用 Pipe
实现进程通信,首先需要调用 multiprocessing.Pipe()
函数来创建一个管道。该函数的语法格式如下:
conn1, conn2 = multiprocessing.Pipe( [duplex=True] )
其中,conn1
和 conn2
分别用来接收 Pipe
函数返回的 2
个端口;duplex
参数默认为 True
,表示该管道是双向的,即位于 2
个端口的进程既可以发送数据,也可以接受数据。
而如果将 duplex
值设为 False
,则表示管道是单向的,conn1
只能用来接收数据,而 conn2
只能用来发送数据。
另外值得一提的是,conn1
和 conn2
都属于 PipeConnection
对象,它们还可以调用下列表所示的这些方法。
Pipe
对象可调用的方法。
方法名 | 功能 |
---|---|
send(obj) | 发送一个 obj 给管道的另一端,另一端使用 recv() 方法接收。需要说明的是,该 obj 必须是可序列化的,如果该对象序列化之后超过 32MB,则很可能会引发 ValueError 异常。 |
recv() | 接收另一端通过 send() 方法发送过来的数据。 |
close() | 关闭连接。 |
poll([timeout]) | 返回连接中是否还有数据可以读取。 |
send_bytes(buffer[,offset[,size]]) | 发送字节数据。如果没有指定 offset、size 参数,则默认发送 buffer 字节串的全部数据;如果指定了 offset 和 size 参数,则只发送 buffer 字节串中从 offset 开始、长度为 size 的字节数据。通过该方法发送的数据,应该使用 recv_bytes() 或 recv_bytes_into 方法接收。 |
recv_bytes([maxlength]) | 接收通过 send_bytes() 方法发送的数据,maxlength 指定最多接收的字节数。该方法返回接收到的字节数据。 |
recv_bytes_into(buffer[,offset]) | 功能与 recv_bytes() 方法类似,只是该方法将接收到的数据放在 buffer 中。 |
下面程序演示了如何使用 Pipe
管道实现 2
个进程之间通信:
1 | import multiprocessing |
程序执行结果为:
28904 进程发送数据: http://c.biancheng.net/python/
28880 接收数据:
http://c.biancheng.net/python/
进阶
管道是堵塞的
1 | import multiprocessing |
输出
1 | 0 |
如果 pipe 不是堵塞的,那么
1 | def processFun(conn): |
将会无限的刷 “接收到数据了”
管道中的缓存
1 | import multiprocessing |
输出
1 | 发送数据 |
可以发现,管道接收能接收到之前的传递进来的数据。
双向管道
双向管道在这里不再说明,请参考相关的参考资料。
其他
如果 Pipe 创建过多,会出现 open too many files