内存映射,简而言之便是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修正可以直接反映到内核空间,相同,内核空间对这段区域的修正也直接反映用户空间。那么关于内核空间<---->用户空间两者之间需求很多数据传输等操作的话功率是十分高的。
以下是一个把遍及文件映射到用户空间的内存区域的示意图。
图一:
二、根本函数
mmap函数是unix/linux下的体系调用,详细内容可参阅《Unix Netword programming》卷二12.2节。
mmap体系调用并不是彻底为了用于同享内存而规划的。它自身供给了不同于一般对一般文件的拜访办法,进程可以像读写内存相同对一般文件的操作。而Posix或体系V的同享内存IPC则朴实用于同享意图,当然mmap()完成同享内存也是其主要使用之一。
mmap体系调用使得进程之间经过映射同一个一般文件完成同享内存。一般文件被映射到进程地址空间后,进程可以像拜访一般内存相同对文件进行拜访,不必再调用read(),write()等操作。mmap并不分配空间, 仅仅将文件映射到调用进程的地址空间里(可是会占掉你的 virutal memory), 然后你就可以用memcpy等操作写文件, 而不必write()了.写完后,内存中的内容并不会当即更新到文件中,而是有一段时间的推迟,你可以调用msync()来显式同步一下, 这样你所写的内容就能当即保存到文件里了.这点应该和驱动相关。 不过经过mmap来写文件这种办法没办法添加文件的长度, 因为要映射的长度在调用mmap()的时分就决议了.假如想撤销内存映射,可以调用munmap()来撤销内存映射
void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)
mmap用于把文件映射到内存空间中,简单说mmap便是把一个文件的内容在内存里边做一个映像。映射成功后,用户对这段内存区域的修正可以直接反映到内核空间,相同,内核空间对这段区域的修正也直接反映用户空间。那么关于内核空间<---->用户空间两者之间需求很多数据传输等操作的话功率是十分高的。
原理
首要,“映射”这个词,就和数学课上说的“逐个映射”是一个意思,便是树立一种逐个对应联系,在这里主要是只 硬盘上文件 的方位与进程 逻辑地址空间 中一块巨细相同的区域之间的逐个对应,如图1中进程1所示。这种对应联系纯属是逻辑上的概念,物理上是不存在的,原因是进程的逻辑地址空间自身便是不存在的。在内存映射的进程中,并没有实践的数据复制,文件没有被载入内存,仅仅逻辑上被放入了内存,详细到代码,便是树立并初始化了相关的数据结构(struct address_space),这个进程有体系调用mmap()完成,所以树立内存映射的功率很高。
图1.内存映射原理
已然树立内存映射没有进行实践的数据复制,那么进程又怎么能终究直接经过内存操作拜访到硬盘上的文件呢?那就要看内存映射之后的几个相关的进程了。
mmap()会回来一个指针ptr,它指向进程逻辑地址空间中的一个地址,这样今后,进程无需再调用read或write对文件进行读写,而只需求经过ptr就可以操作文件。可是ptr所指向的是一个逻辑地址,要操作其间的数据,有必要经过MMU将逻辑地址转换成物理地址,如图1中进程2所示。这个进程与内存映射无关。
前面讲过,树立内存映射并没有实践复制数据,这时,MMU在地址映射表中是无法找到与ptr相对应的物理地址的,也便是MMU失利,将发生一个缺页中止,缺页中止的中止响应函数会在swap中寻觅相对应的页面,假如找不到(也便是该文件从来没有被读入内存的状况),则会经过mmap()树立的映射联系,从硬盘大将文件读取到物理内存中,如图1中进程3所示。这个进程与内存映射无关。
假如在复制数据时,发现物理内存不够用,则会经过虚拟内存机制(swap)将暂时不必的物理页面交换到硬盘上,如图1中进程4所示。这个进程也与内存映射无关。
功率
从代码层面上看,从硬盘大将文件读入内存,都要经过文件体系进行数据复制,而且数据复制操作是由文件体系和硬件驱动完成的,理论上来说,复制数据的功率是相同的。可是经过内存映射的办法拜访硬盘上的文件,功率要比read和write体系调用高,这是为什么呢?原因是read()是体系调用,其间进行了数据复制,它首要将文件内容从硬盘复制到内核空间的一个缓冲区,如图2中进程1,然后再将这些数据复制到用户空间,如图2中进程2,在这个进程中,实践上完成了 两次数据复制 ;而mmap()也是体系调用,如前所述,mmap()中没有进行数据复制,真实的数据复制是在缺页中止处理时进行的,因为mmap()将文件直接映射到用户空间,所以中止处理函数依据这个映射联系,直接将文件从硬盘复制到用户空间,只进行了 一次数据复制 。因而,内存映射的功率要比read/write功率高。
图2.read体系调用原理