Linux 共享内存(Shared Memory)
概述
共享内存是 Linux 中进程间通信(IPC)的一种高效机制。它允许多个进程直接访问同一块物理内存区域,避免了数据拷贝的开销,是速度最快的 IPC 方式。
核心特点
- 高效性:进程直接读写内存,无需系统调用或数据复制。
- 无结构化:共享内存本身不提供同步机制,需结合其他方式(如信号量)保证数据一致性。
- 内核持久性:共享内存区域在内核中维护,直到显式删除或系统重启。
实现方式
Linux 支持两种共享内存实现:
类型 | 特点 |
---|---|
System V | 传统实现方式,通过 shmget /shmat 等函数操作。 |
POSIX | 现代实现方式,基于内存映射文件(mmap ),更符合 POSIX 标准。 |
System V 共享内存操作步骤
1. 创建/获取共享内存
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
- 参数:
- key:唯一标识符(通常用 ftok() 生成)
-
size:共享内存大小(字节)
-
shmflg:权限标志(如 IPC_CREAT | 0666)
-
返回值:共享内存标识符(shmid)
- 附加到进程地址空间
void *shmat(int shmid, const void *shmaddr, int shmflg);
-
参数:
-
shmid:共享内存标识符
-
shmaddr:指定附加地址(通常设为 NULL,由系统选择)
-
shmflg:附加标志(如 SHM_RDONLY 只读访问)
-
-
返回值:指向共享内存的指针
- 使用共享内存
// 写入数据
sprintf((char*)shared_memory, "Hello from PID %d", getpid());
// 读取数据
printf("Received: %s\n", (char*)shared_memory);
- 分离共享内存
int shmdt(const void *shmaddr);
- 参数:shmaddr 为 shmat() 返回的指针
- 删除共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
- 用法:设置 cmd 为 IPC_RMID
shmctl(shmid, IPC_RMID, NULL);
POSIX 共享内存示例
#include <sys/mman.h>
#include <fcntl.h>
// 创建共享内存对象
int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
ftruncate(fd, SIZE);
// 映射到进程地址空间
void *ptr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// 使用后清理
munmap(ptr, SIZE);
shm_unlink("/my_shm");
常用命令
# 查看所有共享内存段
ipcs -m
# 删除共享内存段(System V)
ipcrm -m <shmid>
# 查看 POSIX 共享内存对象
ls /dev/shm