進程間通信(Inter-Process Communication,IPC)是現代作業系統中實現多任務協作的基石。無論是微服務架構中的服務協作,還是單機多進程應用的資料交換,掌握 IPC 核心機制都是系統程式設計師的必修課。本文系統梳理 IPC 基礎概念、主流機制原理與關鍵系統呼叫,助您建立完整知識體系。
進程是擁有獨立位址空間的指令執行序列,是系統資源分配的基本單位。每個進程擁有獨立的虛擬記憶體空間、檔案描述符表、訊號處理表等資源,預設情況下彼此隔離,無法直接存取彼此記憶體。
IPC 的本質是打破進程隔離,實現資料或控制資訊的傳遞。根據資料量與同步需求,可分為:
源自 BSD,提供統一介面支援本機(Unix Domain Socket)與網路(TCP/UDP)通信,現代分布式系統基石。
封裝網路通訊細節,讓遠端呼叫如同本地函式呼叫,支援異構語言互操作(gRPC、Thrift、DCOM 等)。
kill() 系統呼叫、終端按鍵(Ctrl+C → SIGINT)struct sigaction {
void (*sa_handler)(int); // 舊式處理函式
void (*sa_sigaction)(int, siginfo_t *, void *); // 新式,含 siginfo_t
sigset_t sa_mask; // 執行處理函式時暫時阻塞的訊號集
int sa_flags; // SA_SIGINFO, SA_RESTART, SA_NOCLDSTOP 等
void (*sa_restorer)(void); // 已棄用
};
| 函式 | 用途 |
|---|---|
sigaction() | 安裝/查詢訊號處理器,替代舊式 signal() |
sigprocmask() | 讀取/修改進程訊號屏蔽字 |
sigpending() | 檢查 pending 訊號集 |
sigsuspend() | 原子性地暫時替換屏蔽字並休眠,常用於等待特定訊號 |
sigqueue() | 發送帶資料的實時訊號(POSIX.1b) |
sigemptyset(set) // 清空集合
sigfillset(set) // 填入所有訊號
sigaddset(set, sig) // 加入指定訊號
sigdelset(set, sig) // 移除指定訊號
sigismember(set, sig) // 判斷是否在集合中
pipe(fd) 回讀端 fd[0]、寫端 fd[1]fcntl(F_SETPIPE_SZ) 調整)mkfifo(path, mode) 建立檔案系統節點O_NONBLOCK 實現非阻塞開啟// 建立/獲取
int shmid = shmget(key, size, IPC_CREAT | 0666);
// 掛接到進程位址空間
void *addr = shmat(shmid, NULL, 0);
// 使用記憶體...
// 脫離
shmdt(addr);
// 刪除(標記刪除,最後一個 detach 時真正釋放)
shmctl(shmid, IPC_RMID, NULL);
// P 操作:獲取資源
struct sembuf p = {0, -1, SEM_UNDO};
semop(semid, &p, 1);
// V 操作:釋放資源
struct sembuf v = {0, +1, SEM_UNDO};
semop(semid, &v, 1);
SEM_UNDO 確保進程異常終止時核心自動復原信號量值,避免死鎖。
shm_open() + mmap(),語義更清晰,支援檔案系統路徑sem_open()(命名)或 sem_init()(無名,執行緒間),API 更簡潔mq_open() 等,支援優先級、非阻塞、通知機制| 場景 | 推薦機制 | 關鍵考量 |
|---|---|---|
| 父子進程單向資料流 | 無名管道 | 簡單、無需命名、自動清理 |
| 非親緣進程本機通信 | Unix Domain Socket / 命名管道 | Socket 支援雙向、傳遞檔案描述符 |
| 高頻大量資料交換 | 共享記憶體 + 信號量/無鎖佇列 | 零拷貝、延遲最低,同步複雜度高 |
| 跨主機/異構語言 | TCP Socket / gRPC | 標準化、可路由、支援序列化協議 |
| 簡單同步/互斥 | POSIX 信號量 / futex | 輕量級、用戶態快速路徑 |
IPC 是作業系統理論與實踐交匯的核心領域。從訊號的非同步通知,到共享記憶體的零拷貝高效傳輸,每種機制都有其獨特的適用場景與權衡。現代開發中,建議優先考慮高層抽象庫(如 gRPC、ZeroMQ),僅在效能極致敏感或特殊系統級場景下直接操作底層 IPC 原語。深入理解核心機制,能讓您在架構選型、效能調優、疑難排查時遊刃有餘。