1.什么是共享内存
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它瑞典进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
1.2 mmap函数
- 功能,将文件或者设备空间映射到共享内存区
- 原型
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
//addr:要映射的起始地址,通常指定为NULL,让内核自动选择
//len:映射到进程地址空间的字节数
//prot:映射区保护方式
//flags:标志
//fd:文件描述符
//offset:从文件头开始的偏移量
- 返回值,成功返回映射到的内存区的起始地址,失败返回-1
1.3 munmap函数
- 功能,取消mmap函数建立的映射
- 原型
int munmap(void *addr, size_t len);
//addr:映射的内存起始地址
//len:映射到进程地址空间的字节数
- 返回值,成功返回0.失败返回-1
1.4 msync函数
- 功能,对映射的共享内存执行同步操作
- 原型
int msync(void *addr, size_t len, int flags);
//addr:内存起始地址
//len:长度
//flags:选项
- 返回值,成功返回0,失败返回-1
1.5 map注意点
- 映射不能改变文件大小
- 可用于进程间通信的有效地址空间不完全受限于被映射文件的大小
- 文件一旦被映射后,所有对映射区域的访问实际上是对内存区域的访问。映射区域内容写会文件时,所写内容不能超过文件的大小。
2.System V共享内存数据结构
struct shmid_ds{
struct ipc_perm shm_perm; //IPC对象数据结构
size_t shm_segsz; //共享内存段大小
time_t shm_atime; //最后一次映射共享内存时间
time_t shm_dtime; //最后一次解除映射共享内存时间
time_t shm_ctime; //最后一次改变映射共享内存时间
pid_t shm_cpid; //共享内存创建者进程id
pid_t shm_lpid; //最后一次连接或脱离共享内存进程id
shmatt_t shm_nattch; //当前共享内存被连接的次数
...
}
2.1 shmget函数
- 功能,用来创建共享内存
- 原型
int shmget(key_t key, size_t size, int shmflg);
//key:这个共享内存段名字
//size:共享内存大小
//shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
- 返回值:成功返回一个非负整数,即该共享内存段的标识码,失败返回-1
2.2 shmat函数
- 功能,将共享内存段连接到进程地址空间
- 原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
//shmid:共享内存标识码
//shmaddr:指定连接的地址
//shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
- 返回值,成功返回一个指针,指向共享内存第一个字节,失败返回-1
2.3 shmdt函数
- 功能,将共享内存段与当前进程脱离
- 原型
int shmdt(const void *shmaddr);
//shmaddr:由shmat所返回的指针
- 返回值,成功返回0,失败返回-1
- 注意,将共享内存段与当前进程脱离不等于删除共享内存段
2.4 shmctl函数
- 功能,用来创建和访问一个消息队列
- 原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//shmid:由shmget返回的共享内存标识码
//cmd:将要采取瑞典动作,有三个值可取
//buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
- 返回值,成功返回0,失败返回-1