内存映射
1.简介
mmap()系统调用在调用进程的虚拟地址空间中创建一个新内存映射,映射的类型分为两种
-
文件映射
文件映射将一个文件的一部分直接映射到进程的虚拟地址空间中,映射之后,就可以通过进程的虚拟地址访问文件内容
-
匿名映射
匿名映射没有对应的文件,这种映射的分页会被初始化为0
映射之间的共享,根据进程之间映射内容的变更是否可见,可以将映射分为私有的和共享的
-
私有映射(MAP_PRIVATE)
在映射内容上发生的变更对其他进程不可见,如果是文件映射,那么不会修改底层文件内容。内核采用了写时拷贝的技术完成了这个任务,当一个进程试图修改文件内容时,内核会为其创建一个新的物理内存分页,并且将该进程的页表中的条目指向该新的分页
-
共享映射(MAP_SHARED)
在映射内容上发生的变更会对所有共享同一个映射的所有进程可见,对于文件映射来将,变更将会发生在底层文件上
总结:
fork()与exec()与映射
-
通过fork()创建的子进程会继承其父进程的映射的副本,并且这些映射初始时所引用的物理分页与父进程所引用的分页相同
如果采用的是私有映射,那么当父子进程中的某一个对文件做出修改后会创建新的文件分页,父子进程引用不同的文件分页
如果采用的是共享映射,那么父子进程引用相同的文件分页
映射的类型(MAP_PRIVATE和MAP_SHARED)也会在fork()的过程中被继承
-
一个进程在执行exec()时映射会丢失
2.创建一个映射
mmap()系统调用在调用进程的虚拟地址空间中创建一个新映射
#include<sys/mmap.h>
void *mmap(void *addr, seize_t length, int prot, int flags, int fd, off_t offset);
//成功: 返回映射区域的首地址 失败:返回MAP_FAILED
参数解释
-
addr
指定了映射被放置的虚拟地址,可以有以下取值
-
NULL
此时内核会为映射选择一个合适的地址(推荐)
-
非NULL
将指定的地址舍入到最近的一个内存分页处,如果flags包含了MAP_FIXED标志,那么必须是分页对齐的
-
-
length