pin_drop当前位置:知识文库 ❯ 图文

进程间通信Pipe详解 - Python双向管道send/recv

概述

multiprocessing.Pipe 是Python多进程模块提供的双向管道通信机制。与Queue不同,Pipe创建的是两个连接端点,通常用于两个进程之间的高效数据交换。

Pipe的底层基于操作系统管道实现,数据以字节流的形式在管道中传输。它比Queue更轻量、更快,但不支持多对多通信场景。当需要在两个进程间进行双向对话时,Pipe是理想选择。


语法

代码示例

from multiprocessing import Process, Pipe

# 创建管道
parent_conn, child_conn = Pipe(duplex=True)

# 参数说明:
# duplex: True为双向管道(默认),False为单向管道
#   - duplex=True:  两个端点都可以send和recv
#   - duplex=False: 第一个端点只能recv,第二个端点只能send

# 连接端点的常用方法:
# conn.send(obj)       — 发送对象(自动pickle序列化)
# conn.recv()          — 接收对象(阻塞等待)
# conn.poll(timeout)   — 检查是否有数据可读
# conn.close()         — 关闭连接

基本用法

双向通信

代码示例

from multiprocessing import Process, Pipe

def child_process(conn):
    """子进程:接收父进程消息并回复"""
    msg = conn.recv()
    print(f"子进程收到: {msg}")
    conn.send("你好,父进程!")
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    
    p = Process(target=child_process, args=(child_conn,))
    p.start()
    
    parent_conn.send("你好,子进程!")
    reply = parent_conn.recv()
    print(f"父进程收到: {reply}")
    
    p.join()

单向管道

代码示例

from multiprocessing import Process, Pipe

def sender(conn):
    """发送端"""
    for i in range(5):
        conn.send(f"消息{i}")
    conn.close()

def receiver(conn):
    """接收端"""
    while conn.poll():
        msg = conn.recv()
        print(f"收到: {msg}")
    conn.close()

if __name__ == '__main__':
    # duplex=False: recv_conn只能接收, send_conn只能发送
    recv_conn, send_conn = Pipe(duplex=False)
    
    p1 = Process(target=sender, args=(send_conn,))
    p2 = Process(target=receiver, args=(recv_conn,))
    
    p1.start()
    p2.start()
    
    p1.join()
    p2.join()

代码示例

示例:请求-响应模式

代码示例

from multiprocessing import Process, Pipe
import time

def server(conn):
    """服务端:接收请求,返回响应"""
    while True:
        request = conn.recv()
        if request == "QUIT":
            break
        print(f"服务端收到请求: {request}")
        time.sleep(0.5)  # 模拟处理时间
        response = f"已处理: {request}"
        conn.send(response)
    conn.close()
    print("服务端关闭")

def client(conn):
    """客户端:发送请求,等待响应"""
    requests = ["查询用户", "更新数据", "删除记录"]
    for req in requests:
        conn.send(req)
        response = conn.recv()
        print(f"客户端收到响应: {response}")
    conn.send("QUIT")
    conn.close()
    print("客户端关闭")

if __name__ == '__main__':
    conn1, conn2 = Pipe()
    
    s = Process(target=server, args=(conn1,))
    c = Process(target=client, args=(conn2,))
    
    s.start()
    c.start()
    
    s.join()
    c.join()
对比项 Pipe Queue
通信方向 双向 单向(FIFO)
多进程支持 适合两个进程间通信 支持多生产者、多消费者
数据安全 多进程写入需额外锁 进程安全(内置锁)
性能 更快(轻量级) 稍慢(额外锁开销)
适用场景 一对一双向通信 任务分发、消息队列

注意事项

注意1:多个进程同时写入同一个Pipe端点可能导致数据损坏。如果需要多进程写入,应使用Queue或自行加锁。

注意2:使用完毕后应调用 conn.close() 关闭连接端点,避免资源泄漏。

注意3:使用 poll(timeout) 可以在接收前检查是否有数据可读,避免recv()无限阻塞。


小结

  • Pipe:创建双向管道,返回两个连接端点,适合两进程间通信

  • send/recv:send发送对象,recv接收对象,均自动pickle序列化

  • 性能优势:比Queue更轻量快速,适合一对一通信场景

  • 限制:不支持多对多通信,多进程写入需额外同步


练习题

练习1

编写程序,使用Pipe实现父子进程间的双向通信:父进程发送一组数字给子进程,子进程计算它们的平方后返回给父进程。

练习2

编写一个函数,使用Pipe实现一个简单的"ping-pong"游戏:两个进程交替发送和接收消息,模拟乒乓球来回,直到达到指定次数后结束。

常见问题

Pipe和Queue应该如何选择?

如果是严格的一对一双向通信且追求性能,选择Pipe。如果需要多生产者多消费者的任务分发场景,选择Queue。Queue更安全方便,Pipe更快但使用限制更多。

Pipe传递的数据有大小限制吗?

操作系统管道有缓冲区大小限制(通常64KB左右)。如果发送的数据超过缓冲区大小,send()会阻塞直到接收端取走数据。对于大数据量传输,建议分块发送或使用共享内存。

如何检测Pipe中是否有数据可读?

使用conn.poll(timeout)方法。不传参数时立即返回True/False表示是否有数据;传入timeout参数(秒)则会等待指定时间。这可以避免recv()无限阻塞。

标签: Pipe 进程通信 双向管道 多进程 Python教程

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: 进程间通信Queue详解 - Python生产者消费者模式 下一篇: Python进程池Pool完全指南:apply/map/apply_async实战详解 - 小确幸生活

poll相关推荐