进程间通信(3)-共享内存
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; }