概述
共享内存是 linux 中进程间通信(ipc)的一种高效机制。它允许多个进程直接访问同一块物理内存区域,避免了数据拷贝的开销,是速度最快的 ipc 方式。
核心特点
- 高效性:进程直接读写内存,无需系统调用或数据复制。
- 无结构化:共享内存本身不提供同步机制,需结合其他方式(如信号量)保证数据一致性。
- 内核持久性:共享内存区域在内核中维护,直到显式删除或系统重启。
实现方式
linux 支持两种共享内存实现:
类型 | 特点 |
---|---|
system v | 传统实现方式,通过 shmget /shmat 等函数操作。 |
posix | 现代实现方式,基于内存映射文件(mmap ),更符合 posix 标准。 |
system v 共享内存操作步骤
1. 创建/获取共享内存
#include
#include
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
#include
// 创建共享内存对象
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
# 查看 posix 共享内存对象
ls /dev/shm