您的位置 首页 制造

浅析linux内存映射原理

浅析linux内存映射原理-内存映射,简而言之就是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。

内存映射,简而言之便是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修正可以直接反映到内核空间,相同,内核空间对这段区域的修正也直接反映用户空间。那么关于内核空间<---->用户空间两者之间需求很多数据传输等操作的话功率是十分高的。

以下是一个把遍及文件映射到用户空间的内存区域的示意图。

图一:

浅析linux内存映射原理

二、根本函数

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()完成,所以树立内存映射的功率很高。

浅析linux内存映射原理

图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功率高。

浅析linux内存映射原理

图2.read体系调用原理

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/zhizao/98238.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部