操作流程五步驟
shmget():建立或取得共享記憶體段,回傳 ID。
shmat():將共享記憶體映射至當前進程位址空間,回傳指標。
- 讀寫資料:直接透過指標存取結構化資料。
shmdt():解除映射。
shmctl(IPC_RMID) 或指令 ipcrm 刪除共享記憶體段。
完整範例:兩進程透過共享記憶體交換結構體陣列
寫入端
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
typedef struct { char name[4]; int age; } people;
int main() {
key_t key = ftok("/dev/shm/myshm2", 0);
int shm_id = shmget(key, 4096, IPC_CREAT | 0666);
people *p_map = (people*)shmat(shm_id, NULL, 0);
char temp = 'a';
for (int i=0; i<10; i++) {
temp++;
memcpy((p_map+i)->name, &temp, 1);
(p_map+i)->age = 20 + i;
}
shmdt(p_map);
return 0;
}
讀取端
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
typedef struct { char name[4]; int age; } people;
int main() {
key_t key = ftok("/dev/shm/myshm2", 0);
int shm_id = shmget(key, 4096, IPC_CREAT | 0666);
people *p_map = (people*)shmat(shm_id, NULL, 0);
for (int i=0; i<10; i++) {
printf("name: %s age: %d\n", (p_map+i)->name, (p_map+i)->age);
}
shmdt(p_map);
return 0;
}
編譯執行
gcc -o write write.c
gcc -o read read.c
./write
./read
關鍵點補充
ftok() 由路徑名與專案 ID 產生 key,雙方必須一致。
- 共享記憶體實際對應
/dev/shm/ 下的特殊檔案系統節點。
- 多進程並發讀寫時,務必加上訊號量或互斥鎖同步。
- 進程異常結束未
shmdt 時,核心會自動解除映射,但共享記憶體段仍存在,需手動或啟動腳本清理。