python的进程间通信
Python 的进程间通信(Inter-Process Communication,IPC)指不同进程之间如何交换数据。
由于每个进程都有独立的内存空间(互不共享),因此必须借助 操作系统提供的通信机制 来传递信息。
⸻
🧩 一、为什么进程之间要通信?
• 每个进程都是独立的,无法直接读写对方内存。
• 当多个进程协作完成一个任务(例如生产者-消费者、任务分发、结果汇总)时,必须共享一些数据或状态。
• 操作系统提供多种机制来完成这一点(管道、队列、共享内存、Socket 等)。
⸻
🧠 二、Python 提供的主要 IPC 方式
Python 的 multiprocessing 模块对操作系统的 IPC 做了封装。
常用的通信方式如下表:
⸻
🔹 1. Queue(队列通信)
🧩 原理
底层由 Pipe + Lock 实现,线程/进程安全。生产者将数据放入队列,消费者从中取出。
📘 示例
from multiprocessing import Process, Queue
import time, osdef worker(q):print(f"子进程 {os.getpid()} 接收消息...")msg = q.get() # 从队列取数据(阻塞)print(f"子进程收到: {msg}")if __name__ == "__main__":q = Queue()p = Process(target=worker, args=(q,))p.start()q.put("来自主进程的问候 👋")p.join()
优点:线程/进程安全;支持多生产者多消费者。
缺点:数据序列化后传输(pickle),大对象性能稍低。
⸻
🔹 2. Pipe(管道通信)
🧩 原理
Pipe() 返回一对连接对象 (conn1, conn2);双向通信;常用于两个进程之间。
📘 示例
from multiprocessing import Process, Pipedef child(conn):msg = conn.recv() # 等待消息print(f"子进程收到:{msg}")conn.send("子进程已处理✅")conn.close()if __name__ == "__main__":parent_conn, child_conn = Pipe()p = Process(target=child, args=(child_conn,))p.start()parent_conn.send("主进程发送任务")print(parent_conn.recv())p.join()
优点:高效、轻量。
缺点:仅适用于两个进程之间。
⸻
🔹 3. Value / Array(共享内存)
🧩 原理
在 C 层面创建共享内存区(不拷贝),不同进程通过引用访问。
仅支持简单类型(数字、字符、数组)。
📘 示例
from multiprocessing import Process, Value, Arraydef worker(num, arr):num.value += 1for i in range(len(arr)):arr[i] *= 2if __name__ == "__main__":num = Value('i', 10) # 整型共享变量arr = Array('i', [1, 2, 3, 4]) # 整型共享数组p = Process(target=worker, args=(num, arr))p.start(); p.join()print(num.value, arr[:])
优点:真正的内存共享,零拷贝。
缺点:仅限基础类型,不适合复杂对象;需要显式加锁同步。
⸻
🔹 4. Manager(共享对象服务器)
🧩 原理
multiprocessing.Manager() 启动一个服务进程,通过代理对象实现跨进程共享。
支持 list、dict、Namespace 等。
📘 示例
from multiprocessing import Process, Managerdef worker(d, l):d['pid'] = 'worker'l.append('data from worker')if __name__ == "__main__":with Manager() as manager:shared_dict = manager.dict()shared_list = manager.list()p = Process(target=worker, args=(shared_dict, shared_list))p.start(); p.join()print(shared_dict, shared_list)
优点:支持复杂对象、自动同步。
缺点:内部通过 socket 代理通信,性能低于共享内存。
⸻
🔹 5. SharedMemory(Python 3.8+)
🧩 原理
multiprocessing.shared_memory 模块允许进程间直接共享同一块内存区域(零拷贝)。
📘 示例
from multiprocessing import shared_memory, Process
import numpy as npdef child(name, shape):shm = shared_memory.SharedMemory(name=name)arr = np.ndarray(shape, dtype=np.int64, buffer=shm.buf)arr *= 10shm.close()if __name__ == "__main__":a = np.array([1,2,3,4], dtype=np.int64)shm = shared_memory.SharedMemory(create=True, size=a.nbytes)b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)b[:] = a[:]p = Process(target=child, args=(shm.name, a.shape))p.start(); p.join()print(b) # [10 20 30 40]shm.close(); shm.unlink()
优点:零拷贝,速度极快,适合大规模数据共享(如 NumPy)。
缺点:需手动释放、需自行加锁防竞争。
⸻
🔹 6. Socket(网络通信)
🧩 原理
通过 TCP/UDP 套接字通信,跨主机通信必选方案。
📘 示例
# server.py
import socket
s = socket.socket()
s.bind(('localhost', 9999))
s.listen(1)
conn, addr = s.accept()
print(conn.recv(1024).decode())
conn.send(b"hello from server")
conn.close()# client.py
import socket
s = socket.socket()
s.connect(('localhost', 9999))
s.send(b"hello from client")
print(s.recv(1024).decode())
s.close()
优点:通用、跨机器。
缺点:需手动协议编解码,开销相对较高。
⸻
⚙️ 三、性能与应用选择建议
⸻
🧠 四、核心原理图示
┌───────────────────────────────┐
│ 主进程 │
│ ┌───────────────┐ │
│ │ Queue/Pipe │◄────────┐ │
│ └───────────────┘ │ │
│ │ │
└──────────────────────────────┘ │
▲ │
│IPC 通信 │
▼ │
┌───────────────────────────────┐│
│ 子进程1 ││
│ 子进程2 ││
│ 子进程3 ││
└───────────────────────────────┘┘
每个进程独立运行,通信通过操作系统中介(管道、共享内存、socket)完成。
⸻
✅ 五、总结