管道也是一种进程间互相通信的方法,它和队列相比,它是队列的底层实现方法,因此在平常的应用中也比队列更加少见,但是理解它对进程间的通信有很大的帮助
简单例子
from multiprocessing import Pipe
conn1,conn2 = Pipe()
conn1.send('123456')
print(conn2.recv())
其实管道的基本使用非常简单,就是一个管道的类实例化之后会生成两个实例对象,就类似于管道的两个端点,从一头发出的消息会被另一端接收到。
可以看到和tcp传递消息很相似,而管道和tcp都是留用socket套接字来传递消息,区别在于一个是网络套接字,一个是本地文件套接字。
关于阻塞
由于当管道开启之后,会一直堵塞进程用于接收消息,即使没有消息发送之后也会一直等待,因此我们需要判断后手动管理管道两端
from multiprocessing import Pipe,Process
def func1(conn1,conn2):
conn2.close()
while True:
try:
msg = conn1.recv()
print(msg)
except EOFError: #当只有一端管道关闭的时候,会抛出EOFError异常
conn1.close()
if __name__ == '__main__':
conn1,conn2 = Pipe()
p1 = Process(target=func1,args=(conn1,conn2))
p1.start()
conn1.close()
for i in range(10):
conn2.send("在干嘛")
conn2.close()
pipe的数据不安全性
当有多个进程来从管道中取消息的时候,会有可能多个进程抢占同一个数据,因此管道消费的时候存在数据的不安全性,所以我们在每一个子进程中就要实现一个进程锁,只有拿到锁的人才可以从管道中取得数据。
而队列是数据安全的原因也在于此,它在底层添加了锁。