第48章 System V 共享内存
概述
共享内存不由内核控制,意味着需要某种同步机制使得进程不会同时访问共享内存,它允许两个或多个进程共享一个给定的存储区,因为数据不需要在客户进程和服务器进程之间复制,这是最快的一种IPC
数据结构
struct shmid_ds{struct ipc_perm shm_perm; /* 操作许可 */int shm_segsz; /* 共享内存大小,字节为单位 */__kernel_time_t shm_atime; /* 创建时初始化为0,调用shmat后设置为当前时间 */__kernel_time_t shm_dtime; /* 创建时初始化为0,调用shmdt后设置为当前时间 */__kernel_time_t shm_ctime; /* 创建或每次IPC_SET后设置为当前时间 */__kernel_ipc_pid_t shm_cpid; /* 创建共享内存的PID */__kernel_ipc_pid_t shm_lpid; /* 创建时初始化为0,调用shaat或shadt后设置为调用进程的PID */unsigned short shm_nattch; /* 当前使用该共享内存的进程数量,调用shmat递加,调用shmdt递减 */unsigned short shm_unused; /* compatibility */void *shm_unused2; /* ditto - used by DIPC */void *shm_unused3; /* unused */};
创建或打开一个共享内存
#include <sys/shm.h>int shmget(key_t key, size_t size, int flag);// 若成功,返回共享存储ID,若出错,返回-1// size是共享存储段的长度,如果创建,必须指定size,且其内容初始化为0,如果引用,则将size指定为0flag的取值:IPC_CREAT:若key相关的信号量集不存在,则创建IPC_EXCL:若key相关的信号量存在且指定了IPC_CREAT,返回EEXIST错误SHM_HUGETLB:特权(CAP_IPC_LOCK)进程使用此标记创建一个使用huge page的共享内存,可降低硬件内存管理单元的超前转换缓冲器SHM_NORESERVE:与MAP_NORESERVE在mmap中所起的作用一样
控制操作
int shmctl(int shmid, int cmd, struct shmid_ds *buf);// 若成功,返回0,若出错,返回-1cmd的含义如下:IPC_STAT:读取共享内存区的shmid_ds机构,并将其存储到buf指向的地址IPC_RMID:从系统中删除由shmid指向的共享内存区,以及数据结构shmid_ds,如果当前无进程附加该段,执行删除操作,否则等所有进程已经与该段分离(即shm_nattch字段为0)之后再删除IPC_SET:设置共享内存的shmid_ds结构Linux和Solaris还提供了另外两个命令SHM_LOCK:对共享存储加锁,锁进内存RAMSHM_UNLOCK:对共享存储解锁,允许它被交换出去
使用共享内存
void *shmat(int shmid, const void *addr, int flag);// 若成功,返回指向共享存储段的指针,若出错,返回-1addr==0:内核选择的第一个可用地址上,推荐的方式addr非0且没有指定SHM_RND:连接到addr指定的地址(SHM_RND的意思是取整)addr非0且指定了SHM_RND:连接到addr mod SHMLBA(shared memory low boundary)所表示的地址flag指定为SHM_RDONLY:表示只读,试图更新导致SIGSEGV信号,否则以读写方式连接SHM_REMAP:指定之后addr必须是非0
分离共享内存
int shmdt(const void *addr);// 若成功,返回0,若出错,返回-1// addr是shmat的返回值分离与shmctl的IPC_RMID删除不同
共享内存的限制
- SHMMNI:系统级,所能创建的共享内存标识符数量(shmget,ENOSPC)
- SHMMIN:共享内存段的最小大小,被定义为1(shaget,EINVAL)
- SHMMAX:共享内存段的最大大小,依赖于可用RAM和交换空间(shmget,EINVAL)
- SHMALL:系统级,限制了共享内存内的分页总数,依赖于可用RAM和交换空间(shmget,ENOSPC)
- SHMSEG:系统级,限制了所能附加的共享内存段数量
Linux特有的/proc/sys/kernel/shmmni等可查看
Linux特有的shmctl IPC_INFO操作能够获取一个类型为shminfo的结构,其中包含了各种限制值
