程序間通訊(3)-共享記憶體

lethe1203發表於2024-04-04
Linux 中的共享記憶體是一種程序間通訊的機制,允許多個程序共享同一塊實體記憶體區域。共享記憶體是一種高效的 IPC(程序間通訊)方式,適用於需要頻繁交換資料的情況,因為它不涉及資料的複製,而是直接在記憶體中進行讀寫操作。
在 Linux 中,共享記憶體的使用通常涉及以下幾個步驟:
  1. 建立共享記憶體段:使用 shmget 函式建立一個共享記憶體段,為其指定大小和許可權等引數。
  2. 將共享記憶體連線到程序地址空間:使用 shmat 函式將共享記憶體段連線到當前程序的地址空間中,從而使得程序可以直接訪問共享記憶體中的資料。
  3. 進行資料讀寫操作:在共享記憶體中進行資料的讀寫操作,可以透過指標直接訪問共享記憶體中的資料。
  4. 分離共享記憶體:使用 shmdt 函式將共享記憶體從當前程序的地址空間中分離。
  5. 刪除共享記憶體段(可選):使用 shmctl 函式刪除共享記憶體段,釋放資源。

共享記憶體的相關函式:

享記憶體的相關函式:
shmget(key_t key, size_t size, int shmflg):建立或獲取一個共享記憶體識別符號。
key:共享記憶體的鍵值。
size:共享記憶體的大小。
shmflg:標誌位,指定共享記憶體的許可權和行為,比如 IPC_CREAT 表示如果共享記憶體不存在則建立它。


shmat(int shmid, const void *shmaddr, int shmflg):將共享記憶體段連線到程序的地址空間。
shmid:共享記憶體識別符號。
shmaddr:指定要將共享記憶體連線到程序地址空間的地址,通常設定為 NULL,表示由系統選擇合適的地址。
shmflg:連線標誌,通常為 0。


shmdt(const void *shmaddr):將共享記憶體段從程序的地址空間中分離。
shmaddr:指向共享記憶體段的指標。


shmctl(int shmid, int cmd, struct shmid_ds *buf):控制共享記憶體的狀態。
shmid:共享記憶體識別符號。
cmd:控制命令,比如 IPC_RMID 表示刪除共享記憶體。
buf:指向 shmid_ds 結構的指標,用於獲取或設定共享記憶體的狀態資訊。

寫入共享記憶體shm1.c

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

#define SHM_SIZE 1024  // 共享記憶體大小
#define SHM_KEY 12345678   // 共享記憶體鍵值

int main() {
    int shmid;  // 共享記憶體識別符號

    // 建立共享記憶體段
    if ((shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666)) < 0) {  // SHM_KEY可以透過ftok獲得,此處直接定義為12345678
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 將共享記憶體段連線到當前程序的地址空間
    char *shmaddr;
    if ((shmaddr = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 向共享記憶體寫入資料
    strcpy(shmaddr, "Hello, shared memory!");

    // 分離共享記憶體段
    if (shmdt(shmaddr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    return 0;
}

讀取共享記憶體shm2.c

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

#define SHM_SIZE 1024  // 共享記憶體大小
#define SHM_KEY 12345678   // 共享記憶體鍵值

int main() {
    int shmid;  // 共享記憶體識別符號

    // 獲取共享記憶體段
    if ((shmid = shmget(SHM_KEY, SHM_SIZE, 0666)) < 0) {  // SHM_KEY可以透過ftok獲得,此處直接定義12345678
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 將共享記憶體段連線到當前程序的地址空間
    char *shmaddr;
    if ((shmaddr = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 從共享記憶體讀取資料並列印
    printf("Data read from shared memory: %s\n", shmaddr);

    // 分離共享記憶體段
    if (shmdt(shmaddr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    return 0;
}

執行結果如下:

0

相關文章