Python multiprocessing 模組提供兩種進程間通訊(IPC)機制:Pipe(管道)與 Queue(佇列)。兩者底層皆基於管道實作,但適用場景與 API 設計差異顯著。
multiprocessing.Pipe(duplex=True) 回傳 (conn1, conn2) 兩個連線物件。duplex=True(預設)為雙向,False 為單向(conn1 僅收、conn2 僅送)。send(obj)、recv()、poll(timeout)。import multiprocessing, time
def sender(conn):
for i in range(10):
print(f"發送 {i}")
conn.send(i)
time.sleep(0.5)
conn.close()
def receiver(conn, name):
while True:
msg = conn.recv()
if msg is None: break
print(f"{name} 接收: {msg}")
if __name__ == '__main__':
parent, child = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=sender, args=(child,))
p2 = multiprocessing.Process(target=receiver, args=(parent, 'R1'))
p3 = multiprocessing.Process(target=receiver, args=(parent, 'R2')) # 競爭接收
p1.start(); p2.start(); p3.start()
p1.join(); p2.join(); p3.join()
Queue(maxsize) 可限制長度,預設無上限。put()/get()(阻塞)、put_nowait()/get_nowait()(非阻塞)、qsize()/empty()/full()(不可靠)、close()/join_thread()。import multiprocessing, time
def producer(q):
for i in range(10):
q.put(i)
print(f"放入 {i}")
q.put(None) # 結束信號
def consumer(q, name):
while True:
item = q.get()
if item is None:
q.put(None) # 傳遞給下一個消費者
break
print(f"{name} 處理 {item}")
time.sleep(0.2)
if __name__ == '__main__':
q = multiprocessing.Queue(maxsize=3)
p1 = multiprocessing.Process(target=producer, args=(q,))
c1 = multiprocessing.Process(target=consumer, args=(q, 'C1'))
c2 = multiprocessing.Process(target=consumer, args=(q, 'C2'))
p1.start(); c1.start(); c2.start()
p1.join(); c1.join(); c2.join()
| 特性 | Pipe | Queue |
|---|---|---|
| 通訊模式 | 點對點(1對1) | 多對多(生產者/消費者) |
| 同步機制 | 無內建鎖 | 內建鎖/信號量 |
| 阻塞控制 | 僅阻塞 recv/send | put/get 可設 timeout、nowait |
| 適用場景 | 簡單雙進程資料流 | 任務佇列、並行工作池 |
| 效能 | 略高(較輕量) | 略低(鎖開銷) |
實務上,Queue 是多進程架構的標準選擇;Pipe 僅用於極簡雙進程場景。