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