Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 進程間通訊:共享記憶體 (shmget/shmat/shmdt) 機制詳解與父子進程範例

編輯:Linux 教學

共享記憶體是 IPC 中最快的資料交換方式:一進程寫入,所有掛載該區段的進程立即可見。實作分三步驟:建立、掛載、分離。

核心 API

1. shmget — 取得/建立共享記憶體標識符

int shmget(key_t key, size_t size, int shmflg);
  • key:IPC_PRIVATE (0) 建立新物件;其他值依 ftok 產生。
  • size:新建時指定位元組數;僅取得時填 0。
  • shmflg:0 僅取得;IPC_CREAT 不存在則建立;IPC_CREAT|IPC_EXCL 存在則報錯。
  • 成功回傳 shmid,失敗 -1。

2. shmat — 將共享記憶體映射至進程位址空間

void *shmat(int shmid, const void *shmaddr, int shmflg);
  • shmaddr:指定映射位址,通常傳 NULL 讓核心決定。
  • shmflg:SHM_RDONLY 唯讀,否則讀寫。
  • 成功回傳映射位址,失敗 -1。

3. shmdt — 分離共享記憶體

int shmdt(const void *shmaddr);
  • 傳入 shmat 回傳位址,成功 0,失敗 -1。

父子進程傳遞字串完整範例

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        printf("please input the shared data.\n");
        exit(-1);
    }
    int shmid = shmget(0, 1024, IPC_CREAT);
    if (shmid == -1) {
        printf("create share memory failed.\n");
        exit(-1);
    }
    if (fork()) {                     // 父進程
        char *p_shmaddr = shmat(shmid, NULL, 0);
        memset(p_shmaddr, 0, 1024);
        strcpy(p_shmaddr, argv[1]);   // 寫入共享資料
        wait(NULL);
        exit(0);
    } else {                          // 子進程
        sleep(2);                     // 等父進程寫入
        char *c_shmaddr = shmat(shmid, NULL, 0);
        printf("the share data is: %s\n", c_shmaddr);
        exit(0);
    }
}

編譯執行:gcc -o shm_demo shm_demo.c && ./shm_demo "Hello IPC",子進程將輸出共享字串。實務上還需搭配信號量或互斥鎖同步存取,避免競態條件。

Copyright © Windows教程網 All Rights Reserved