目錄
03-1. IPC 概述
⏱️ 閱讀時間: 8 分鐘 🎯 難度: ⭐⭐ (簡單)
🤔 什麼是 IPC?
IPC (Inter-Process Communication) = 進程間通訊
一句話解釋: 讓不同的 Process 能夠互相傳遞資料和訊息的機制。
🏢 用公司來比喻
公司 A(Process A) 公司 B(Process B)
├─ 辦公室 A ├─ 辦公室 B
├─ 獨立資源 ├─ 獨立資源
└─ 員工 └─ 員工
問題:兩家公司如何溝通?IPC 機制 = 公司間的溝通方式:
- 📞 Pipe = 電話專線
- 📨 Message Queue = 郵件系統
- 📂 Shared Memory = 共用雲端硬碟
- 🌐 Socket = 網路會議
📋 IPC 的五種主要方式
1. Pipe(管道)
特性:
- 單向通訊(A → B)
- 半雙工(需要兩個 Pipe 才能雙向)
- 適合父子 Process
from multiprocessing import Process, Pipe
def sender(conn):
conn.send("你好,這是 Process A")
conn.close()
def receiver(conn):
msg = conn.recv()
print(f"收到訊息: {msg}")
conn.close()
# 創建 Pipe
parent_conn, child_conn = Pipe()
p1 = Process(target=sender, args=(parent_conn,))
p2 = Process(target=receiver, args=(child_conn,))
p1.start()
p2.start()
p1.join()
p2.join()2. Message Queue(消息佇列)
特性:
- 雙向通訊
- 先進先出(FIFO)
- 可以有多個生產者和消費者
from multiprocessing import Process, Queue
def producer(queue):
for i in range(5):
queue.put(f"資料 {i}")
print(f"生產: 資料 {i}")
def consumer(queue):
while True:
try:
msg = queue.get(timeout=1)
print(f"消費: {msg}")
except:
break
queue = Queue()
p1 = Process(target=producer, args=(queue,))
p2 = Process(target=consumer, args=(queue,))
p1.start()
p2.start()
p1.join()
p2.join()3. Shared Memory(共享記憶體)
特性:
- 最快的 IPC 方式
- 需要同步機制(Lock)
- 適合大量資料交換
from multiprocessing import Process, Value, Array
def increment(shared_value, shared_array):
shared_value.value += 1
for i in range(len(shared_array)):
shared_array[i] *= 2
# 創建共享記憶體
shared_value = Value('i', 0) # 整數
shared_array = Array('i', [1, 2, 3, 4, 5]) # 陣列
p = Process(target=increment, args=(shared_value, shared_array))
p.start()
p.join()
print(f"Value: {shared_value.value}")
print(f"Array: {list(shared_array)}")4. Socket(網路通訊)
特性:
- 可以跨網路通訊
- 支援 TCP/UDP
- 最靈活的 IPC 方式
# Server Process
import socket
def server():
s = socket.socket()
s.bind(('localhost', 8888))
s.listen(1)
conn, addr = s.accept()
msg = conn.recv(1024)
print(f"收到: {msg.decode()}")
conn.close()
# Client Process
def client():
s = socket.socket()
s.connect(('localhost', 8888))
s.send(b"Hello from client")
s.close()5. Signal(信號)
特性:
- 異步通知機制
- 用於簡單的事件通知
import signal
import os
import time
def signal_handler(signum, frame):
print("收到信號!")
# 註冊信號處理器
signal.signal(signal.SIGUSR1, signal_handler)
print(f"PID: {os.getpid()}")
# 發送信號給自己
os.kill(os.getpid(), signal.SIGUSR1)
time.sleep(1)📊 IPC 方式對比
| 方式 | 速度 | 複雜度 | 適用場景 |
|---|---|---|---|
| Pipe | 快 | 低 | 父子 Process |
| Message Queue | 中 | 中 | 生產者/消費者 |
| Shared Memory | 最快 | 高 | 大量資料交換 |
| Socket | 慢 | 中 | 跨網路通訊 |
| Signal | 快 | 低 | 事件通知 |
🎯 選擇建議
需要通訊的 Process 關係?
├─ 父子關係 → Pipe
├─ 大量資料 → Shared Memory
├─ 佇列模式 → Message Queue
├─ 跨機器 → Socket
└─ 簡單通知 → Signal下一篇: 03-2. Pipe(管道)
最後更新:2025-01-04