void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *addr, size_t length);
mmap参数
-
addr为内存映射区的地址,一般由内核指定一般传NULL
-
length为映射文件的大小,内核会根据length的大小将其修改为4k的整数倍
-
prot有四个选项
PROT_EXEC Pages may be executed. PROT_READ Pages may be read. PROT_WRITE Pages may be written. PROT_NONE Pages may not be accessed.
-
flags参数比较多,常用的有
MAP_SHARED//修改映射区中的数据的时候会同步到磁盘中 Share this mapping. Updates to the mapping are visible to other processes mapping the same region, and (in the case of file-backed mappings) are carried through to the underlying file. (To precisely control when updates are carried through to the underlying file requires the use of msync(2).) MAP_PRIVATE//修改映射区中的数据的时候不会同步到磁盘中 Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.
-
fd为要映射的文件的文件描述符
-
offset为要映射的文件指针的偏移量,必须为4k的整数倍,也就是4096的整数倍
munmap
- addr参数为映射区的地址,一般为mmap的返回值
- length为映射的文件的长度
注意事项
-
如果munmap的addr参数不是最初mmap返回的映射区的地址,那么会出现错误
-
如果open()打开文件的时候指定的权限小于mmap指定的权限,会出现错误
-
mmap指定文件偏移量的时候必须是4K的整数倍,否则调用会出错
-
mmap第二个参数length不能为零,否则调用会出错
-
mmap的第三个参数prot必须指定PRO_READ权限
-
open的时候可以指定O_CREATE来创建一个新文件来做内存映射,但是必须进行文件拓展
lseek()//必须要进行一次写操作 truncate(pathe,length)
-
映射区创建完成以后,任何时候关闭文件描述符对映射区都没有影响
-
对内存映射区做越界操作会出现段错误
利用mmap进行进程间通信
父子进程间通信,父子进程永远共享文件和内存映射区
用mmap进行通信的优势是直接在内存操作,效率高;
创建匿名映射区进行父子进程间通信
当进行有亲缘关系的进程间通信的时候,使用匿名映射区更简便一点
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
创建匿名映射区的时候,参数会有所变化;
- flags需要加上MAP_ANONYMOUS
- fd需要传入-1
没有血缘关系的进程之间通信不能使用匿名映射区;