Linux内核源码阅读之系统调用mmap()

mmap()

将一个已经打开的文件的内容映射的它的用户空间。

1.解释

“文件的内容映射的它的用户空间”是什么意思?

我们知道linux内核中,物理内存在内存中以页面大小为单位进行维护,而页式内存管理简单的说是给定一个虚拟地址0xA,经过页式映射,能够找到物理内存所对应的页面地址,数据真正存放的位置。

Linux内存管理以页面为单位,对用户空间的管理当然也是以页面为单位,而每个虚存地址都会对应着某个具体页面。

那么上面的那句话就是说在用户空间建立好虚拟地址到页面的映射,将文件的内容读到内存中指定的页面,这样程序可以通过虚拟地址再经过页式映射,就能找到文件在页面中的内容。

那么同样是将文件内容读到内存中,它和普通的文件读取read()有什么不同呢?

a.读取方式不同,mmap()读取文件内容的方式是通过缺页中断,当发现虚拟地址对应的页式映射尚未建立,就会通过缺页中断将文件内容读取到虚存地址所映射的页面中。

而普通的文件读取就是通过read()读取文件内容。

b.访问方式不同,mmap()后,访问文件内容就像访存一样简单。

2.主要步骤

mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)

1.找到一块大小为length的未被映射的虚存空间

2.为找到的虚存空间分配vm_area_struct结构,用来映射后来读到内存页面中的文件内容

3.设置vm_area_struct的各个成员信息,比如将vm_area_struct中的vm_pgoff设置为offset,这样当发生缺页异常时,就会从文件偏移vm_pgoff的地方开始读取文件内容到指定页面。

4.将此vm_area_struct结构插入本进行的vm_area_struct队列中

5.结束

这就结束了?并没有看到具体文件读到内存中的操作啊?甚至连vm_area_struct所对应页面映射都没有建立,页面都没有分配。

其实这里的mmap()仅仅是建立其虚存结构vm_area_struct。而把真正的页面映射推迟到确实需要读取文件内容时,以缺页异常的方式读取。这样做的好处一方面避免不必要的文件读取,因为程序可能建立完映射并不访问文件内容;另一方面,节省不必要的内存页面开销。否则可能会导致频繁的页面换入换出。

参考资料:

《Linux内核情景分析》毛德操,胡希明

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值