System V IPC 是 Unix System V 引入、Linux 完整支援的進程間通信機制族,在核心空間實現三種核心物件:
這三者統稱為 System V IPC 物件,共享同一組核心管理架構。
用戶空間 核心空間
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ Key │───▶│ ID │ (非負整數,通常較大)
│ (key_t) │ │(shmid/ │
│ │ │ msqid/ │
└─────────┘ │ semid) │
└─────────┘
為什麼需要 Key? 核心 ID 是內部不透明控制代碼,用戶程式無法直接猜測。Key 充當「公開名稱」,透過系統呼叫轉換為內部 ID。
| 方式 | 函數/常數 | 特性 | 適用場景 |
|---|---|---|---|
| 指定固定值 | key_t key = 0x1234; | 簡單但易衝突 | 單機單應用、教學測試 |
| 私有鍵值 | IPC_PRIVATE | 每次建立新物件,無名字 | 父子進程、關聯進程間 |
| 路徑衍生 | ftok(pathname, proj_id) | 同路徑同專案 ID 產生同 Key | 無關進程協作、生產環境 |
// ftok 經典用法
key_t key = ftok("/tmp/my_ipc_proj", 'A'); // 路徑必須存在,proj_id 只取低 8 位
if (key == -1) perror("ftok failed");
所有 IPC 物件共享的權限控制結構(簡化版):
struct ipc_perm {
key_t key; // 公開鍵值
uid_t uid; // 擁有者用戶 ID
gid_t gid; // 擁有者群組 ID
uid_t cuid; // 建立者用戶 ID
gid_t cgid; // 建立者群組 ID
mode_t mode; // 存取權限 (r/w 位元)
unsigned long seq; // 序列號,防止 ID 重用攻擊
};
權限位元定義:0600 = 擁有者讀寫,0666 = 所有人讀寫。注意: IPC 物件無執行位元,無目錄概念。
無論哪種 IPC 物件,操作流程高度一致:
shmget() / msgget() / semget()shmat()/shmdt() / msgsnd()/msgrcv() / semop()shmctl() / msgctl() / semctl()$ ipcs ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 163840 talk8 600 33554432 2 dest ------ Semaphore Arrays -------- key semid owner perms nsems 0xcbc384f8 0 tom 600 1 ------ Message Queues -------- key msqid owner perms used-bytes messages
ipcs -m # 僅共享記憶體 ipcs -q # 僅訊息佇列 ipcs -s # 僅信號量
ipcrm -m shmid # 刪除共享記憶體 ipcrm -q msqid # 刪除訊息佇列 ipcrm -s semid # 刪除信號量 # ID 從 ipcs 輸出獲取
cat /proc/sysvipc/shm # 共享記憶體詳情 cat /proc/sysvipc/msg # 訊息佇列詳情 cat /proc/sysvipc/sem # 信號量詳情 # 範例輸出 $ cat /proc/sysvipc/sem key semid perms nsems uid gid cuid cgid otime ctime -876378888 0 600 1 1000 1000 1000 1000 1452336947 1452326
struct shmid_kernel {
struct kern_ipc_perm shm_perm; // 通用權限頭
struct file *shm_file; // 底層檔案物件(tmpfs)
unsigned long shm_nattch; // 當前附掛進程數
unsigned long shm_segsz; // 區段大小 (bytes)
time_t shm_atim; // 最後附掛時間
time_t shm_dtim; // 最後分離時間
time_t shm_ctim; // 最後控制操作時間
pid_t shm_cprid; // 建立者 PID
pid_t shm_lprid; // 最後操作者 PID
struct user_struct *mlock_user; // 鎖定記憶體用戶
struct task_struct *shm_creator;// 建立者任務結構
struct list_head shm_clist; // 建立者鏈表節點
};
kernel.shmmni、kernel.shmmax、kernel.msgmni 等可透過 sysctl 調整shm_open, mq_open, sem_open) 提供檔案系統命名空間整合,新專案優先考慮System V IPC 以「Key-ID 雙層識別」、「統一權限結構」、「三大物件類型」構成經典 Unix IPC 體系。掌握 ftok、ipcs、ipcrm、/proc/sysvipc/* 工具鏈,是 Linux 系統程式開發與除錯的必備技能。下一章將深入共享記憶體 API 實戰。