来源:python中国网 时间:2019-06-06

  管道的本质是在内存中开辟一个新的空间,对多个进程可见,在通信形式上形成一种约束,管道在信息传输上是以流的方式传输,先进先出原则。

  需要程序调用 multiprocessing.Pipe(duplex) 来创建一个管道。该函数会返回两个 PipeConnection 对象,代表管道的两个连接端(一个管道有两个连接端,分别用于连接通信的两个进程)。

  1) 如果duplex为True(默认),则管道是双向的(即每个端同时可以收发信息)

  2) 如果duplex是False,那么管道是单向的:conn1只能用于接收消息,conn2只能用于发送消息。

  3) 默认情况下是双工(双向,即一端可以发消息同时可以收消息)

  PipeConnection 对象包含如下常用方法:

  send(obj):发送一个 obj 给管道的另一端,另一端使用 recv() 方法接收。需要说明的是,该 obj 必须是可 picklable 的(Python 的序列化机制),如果该对象序列化之后超过 32MB,则很可能会引发 ValueError 异常。

  recv():接收另一端通过 send() 方法发送过来的数据。

  fileno():关于连接所使用的文件描述器。

  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 中。

  注意点:

  如果两个进程(或线程)尝试同时读取或写入管道的同一端,管道中的数据可能会损坏,在实现生产者消费者模型中需要加锁。其实管道加锁就是队列的实现!

# ‐*‐ coding: utf‐8 ‐*‐

import multiprocessing
from multiprocessing import Process, Pipe


def proc1(pipe):

    pipe.send("proc1")
    print("进程proc1({0})收到".format(multiprocessing.current_process()),pipe.recv())

def proc2(pipe):

    print("进程proc2({0})收到".format(multiprocessing.current_process()),pipe.recv())
    pipe.send("proc2")


if __name__ == '__main__':

    # 创建一个管道 这个管道是双向的
    pipe = Pipe()

    # pipe[0] 表示管道的一端,pipe[1] 表示管道的另外一端
    p1 = Process(target=proc1,args=(pipe[0],))
    p2 = Process(target=proc2,args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
D:installpython3python.exe D:/pyscript/test/test1.py
进程proc2(<Process(Process-2, started)>)收到 proc1
进程proc1(<Process(Process-1, started)>)收到 proc2

Process finished with exit code 0