进程间通信常见方式-mmap映射区
学习目标:
掌握mmap建立映射区
掌握mmap
mmap函数:
mmap函数: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
addr:指定映射区首地址,传NULL可以让系统自动分配。
fd:用于创建共享内存映射区的文件的文件描述符。
offset:默认0,表示映射文件全部,偏移位置,必须是4K的整数倍。
返回值
成功:映射区首地址。
失败:MAP_PAILED(void*(-1)),设置errno。
munmap函数:
munmap函数:用于释放mmap创建的映射区。
int mmap(void *addr,size_t length);
参数
addr:指定映射区首地址,传NULL可以让系统自动分配。
length:共享内存映射区大小(<= 文件的实际大小)。
返回值
成功:0。
失败:-1,设置errno。
mmap函数使用注意事项:
- 用于创建映射区的文件大小为0,实际指定非0大小创建映射区,出
总线错误
。 - 用于创建映射区的文件大小为0,实际0大小创建映射区,出
无效参数
。 - 用于创建映射区的文件读写属性为只读,映射区属性为读写,出
无效参数
。 - 创建映射区,需要read权限,当访问权限指定为“共享”
MAP_SHARED
时,mmap的读写权限,应该<=文件的open权限。只写不行
。 - 文件描述符fd,在mmap创建映射区完成时即可关闭,后续访问文件,用地址访问。
- offset 必须是4096的整数倍。(MMU映射的最小单位4K)。
- 对申请的映射区内存,不能越界访问。
- munmap用于释放的地址,必须时mmap申请返回的地址。
- 映射区访问权限为"私有"MAP_PRIVATE,对内存有效,不会反应到物理磁盘上。
10.映射区访问权限为"私有"MAP)PRIVATE,只需要open文件时,有读权限,用于创建映射区即可。
补充:
父子进程使用mmap进程间通信:
- 父进程先创建映射区,
- 指定MAP_SHARED权限。
- fork()创建子进程。
- 一个进程读,另一个进程写。
无亲缘关系进程间mmap通信: - 两个进程打开同一个文件,创建映射区。
- 指定flags为MAP_SHARED。
- 一个进程写入,另一个进程写出。
【注意】无亲缘关系进程间通信: - mmap:数据可以重复读取。
- fifo:数据只能一次读取。
匿名映射:只能用于亲缘关系进程间通信
length参数可以任意指定。
prot参数设置MAP_ANON或MAP_ANONYMOUS,flags参数设置-1 。