共享存储
2015-05-16 21:01:40 最后更新: 2015-05-16 21:01:40 访问数量:1639
2015-05-16 21:01:40 最后更新: 2015-05-16 21:01:40 访问数量:1639
共享内存允许两个或更多个进程共享一个给定的存储区域,这是最快的一种 IPC
但是,当某个进程正在读写共享存储的某个区域时,其他进程同时不应该对该区域进行操作,信号量通常被用来实现对共享存储访问的同步,当然,记录所也可以用于这种场合,但是记录锁在时间上要比信号量多消耗约 60%
内核为每个共享存储段设置了一个 shmid_ds 结构
各系统的具体实现会包含额外的字段
函数 shmget 用于创建一个新的共享存储段或获取一个已经存在的共享存储段
定义于 sys/shm.h 中
成功调用返回共享存储段 ID,否则返回 -1
该函数将 key 变换为信号量集标识符,并返回,与消息队列创建函数 msgget 一样:
参数 nsems 用于初始化该信号量集描述结构的 sem_nsems 字段
shmctl 函数可以执行多种操作,与 ioctl、semctl、shmctl 非常类似,都被称为“垃圾桶函数”
定义于 sys/shm.h 中
调用成功返回 0,否则返回 -1
cmd 参数可以指定下列 5 种命令的一种
取值 | 意义 |
IPC_STAT | 获取 shmid 对应的存储段描述结构 shmid_ds 并存储在参数 buf 所指向的内存中 |
IPC_SET | 按 buf 所指向内存中的 shmid_ds 结构设置 shmid 对应的存储段描述结构(可以改变 shm_perm.uid、shm_perm.gid、shm_perm.mode),执行此命令的进程有效用户 ID 必须等于 sem_perm.cuid 或 sem_perm.uid 或者该进程具有超级用户权限 |
IPC_RMID | 从系统中删除该共享存储段,与其他两个 XSI IPC 的相应操作不同,执行后并不会立即删除,除非该存储段的最后一个进程终止或与该段脱离连接(shm_nattch 值变为 0),执行此命令的进程有效用户 ID 必须等于 sem_perm.cuid 或 sem_perm.uid 或者该进程具有超级用户权限 |
SHM_LOCK | 将共享存储段锁定在内存中,只有超级用户可以执行此命令 |
SHM_UNLOCK | 解锁共享内存段,只有超级用户可以执行此命令 |
一旦创建了一个共享存储段,进程就可以通过调用 shmat 函数将它连接到它的地址空间中:
定义于 sys/shm.h 中
调用成功返回指向共享存储地址空间的指针,否则返回 -1
若 addr 为 0,则此段连接到有内核选择的第一个可用地址上(推荐使用)
若 addr 不为 0,则需要参考 flag 参数的值
flag 可以取下列宏的与
取值 | 意义 |
SHM_RND | 连接到 addr 最近的一个 2 的乘方地址上(若未指定该标识,则直接连接到 addr 指向的地址) |
SHM_RDONLY | 连接后,该段只能被以只读方式使用(若未指定该标志,则以读写方式使用) |
shmat 相反的操作即脱离连接,就是 shmdt 函数
定义于 sys/shm.h 中
调用成功返回 0,否则返回 -1
shmdt 的实际操作是将 shm_nattch 的值减 1
欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,只有全部原创,只有干货没有鸡汤