内存映射机制(mmap)

2019-07-14 12:56发布

class="markdown_views prism-tomorrow-night">
  • 当CPU读取数据时,是由内存管理单元(MMU)管理的。MMU位于CPU与物理内存之间,它包含从虚地址向物理内存地址转化的映射信息。当CPU引用一个内存位置时,MMU决定哪些页需要驻留(通常通过移位或屏蔽地址的某些位)以及转化虚拟页号到物理页号。
    在这里插入图片描述
  • 当某个进程读取磁盘上的数据时,进程要求其缓冲通过read()系统调用填满,这个系统调用导致内核想磁盘控制硬件发出一条命令要从磁盘获取数据。磁盘控制器通过DMA直接将数据写入内核的内存缓冲区,不需要CPU协助。当请求read()操作时,一旦磁盘控制器完成了缓存的填写,内核从内核空间的临时缓存拷贝数据到进程指定的缓存中。
  • 用户空间是常规进程所在的区域,该区域执行的代码不能直接访问硬件设备。内核空间是操作系统所在的区域,该区域可以与设备控制器通讯,控制用户区域进程的运行状态。
    在这里插入图片描述
  • 内存映射文件技术是操作系统提供的一种新的文件数据存取机制,利用内存映射文件技术,系统可以在内存空间中为文件保留一部分空间,并将文件映射到这块保留空间,一旦文件被映射后,操作系统将管理页映射缓冲以及高速缓冲等任务,而不需要调用分配、释放内存块和文件输入/输出的API函数,也不需要自己提供任何缓冲算法。
  • 使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O 操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。

linux 内存映射机制

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize) int munmap(void *start, size_t length) mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。 munmap执行相反的操作,删除特定地址区域的对象映射。
在这里插入图片描述
  • 返回说明:
成功执行时,mmap()返回被映射区的指针,munmap()返回0。失败时,mmap()返回MAP_FAILED(其为(void*)-1),munmap 返回-1。
  • 参数:
start:映射区的开始地址。
length:映射区的长度。
prot:映射区域的保护方式。可以为以下几种方式的组合 PROT_EXEC //页内容可以被执行 PROT_READ //页内容可以被读取 PROT_WRITE //页可以被写入 PROT_NONE //页不可访问 flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体 MAP_FIXED //使用指定的映射起始地址,如果由 start和len 参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。 MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到 msync()或者munmap() 被调用,文件实际上不会被更新。 MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。 MAP_DENYWRITE //这个标志被忽略。 MAP_EXECUTABLE //同上 MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。 MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。 MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。 MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。 MAP_ANON //MAP_ANONYMOUS 的别称,不再被使用。 MAP_FILE //兼容标志,被忽略。 MAP_32BIT //将映射区放在进程地址空间的低 2GB,MAP_FIXED 指定时会被忽略。当前这个标志只在 x86-64平台上得到支持。 MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。 MAP_NONBLOCK //仅和MAP_POPULATE 一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。 fd:有效的文件描述词。
offset:被映射对象内容的起点 转载于:https://blog.csdn.net/aspirinvagrant/article/details/18991263