mmap函数
用于创建共享内存映射
- 函数原型
void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);
- 参数
- addr:指定映射的首地址,通常传NULL,表示让系统自动分配
- length:共享内存映射区的大小。(<=文件的实际大小)
- prot:共享内存映射区的读写属性。PROT_READ,PROT_WRITE,PROT_READ|PROT_WRITE
- flags:标注共享内存的共享属性。MAP_SHARED,MAP_PRIVATE
- fd:用于创建共享内存映射区的那个文件的文件描述符
- offset:默认是0,表示映射文件的全部。偏移位置,需是4K的整数倍
- 返回值:
- 成功:映射区的首地址
- 失败:MAP_FAILED
munmap函数
用于释放映射区
int munmap(void *addr, size_t length);
- 参数
- addr:mmp的返回值
- length:共享映射区的大小
- 返回值
- 失败为-1
- 成功返回0
- 注意事项
- 用于映射区大小为0,实际制定大小非0的创建映射区,会出现总线错误
- 用于创建映射区的文件大小为0,实际制定0大小的创建映射区,出无效参数错误
- 用于创建映射区的文件读写属性为只读行为,映射区属性为读写,出现无效参数错误
- 创建映射区需要读read权限
- 文件描述符fd,在mmp创建完映射区即可关闭。后续访问文件可以直接用mmp返回的地址
- offset必须是4096也就是4K的整数倍,因为MMU最小单位是4K
- 对申请的内存,不能越界,否则不安全
- munmap用于释放地址,必须是mmap申请返回的地址
- 映射区访问权限为"私有"时,MAP_PRIVATE,对内存所做的所有修改,只在内存有效,不会反映到物理磁盘上
- 调用方式
- open(O_RDWR)
- mmap(NULL,有效文件大小,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
mmap父子进程通信
- 父子进程可以通过mmap建立映射区完成数据通信
- 私有映射,父子进程各自独占映射区
- 共享映射,父子进程共享映射区
- 父进程先创建共享内存映射区再fork()
匿名映射
void *mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
无血缘关系进程mmap通信
- 两个进程打开同一个文件,创建映射区
- 指定flags为MAP_SHARED
- 一个进程写入一个进程读出
- mmap数据可以多次读取,fifo数据只能一次读取