什么时候选择mmap而非read?
mmap 和 read 系统流程
在linux文件系统中,通常使用open(), read()读取文件,但操作系统同样提供了mmap()作为读取文件的方式,而这两者有什么不同呢?什么时候用read(), 什么时候用mmap()?
首先,read 的通常使用方法是 read(fd, buffer, size),将要读取的数据读到buffer中。这就涉及到两个步骤,read是系统调用函数,每次使用read都要进入内核态,进行上下文切换。内核首先将文件数据从磁盘读入page cache缓存,再将数据从page cache拷贝到buffer中。上下文切换和拷贝要消耗一定性能。
而如果使用 mmap 命令,VFS(虚拟文件系统)会分配对应的虚拟内存空间,记录目标文件的 inode 和其他属性,将起始虚拟地址返回给进程。当进程想要访问某部分数据时,需要进行地址翻译,但此时没有更新页表,会触发缺页中断。linux根据VMA中记录的 inode 信息,调用对应的文件系统进行处理。文件系统读取该页,返回给VFS,VFS再更新页表,返回对应的物理页。
在 mmap 之后,后续的读写操作都是在内存中进行,不需要再读磁盘和进入内核态。
mmap的优点
因此 mmap 比起 read ,有如下优势:
- 对于随机访问,不用频繁 lseek。因为 mmap 是将整个文件映射到虚拟空间,在读取时再按需分配物理内存。
- 减少后续系统调用次数。后续读文件时不需要再进入内核态,减少了上下文切换
- 减少数据拷贝。免去了page cache 到 buffer 的数据拷贝。
- 当多个进程将同一页面映射到内存时,数据可以在这些进程之间共享。对于 只读 的页面可以完全共享,需要写入的文件可以使用COW(copy on write)私有化。这样节省了大量内存。
mmapalso allows the operating system to optimize paging operations. For example, consider two programs; programAwhich reads in a1MBfile into a buffer creating withmalloc, and program B whichmmapsthe 1MB file into memory. If the operating system has to swap part ofA's memory out, it must write the contents of the buffer to swap before it can reuse the memory. InB's case any unmodifiedmmap'd pages can be reused immediately because the OS knows how to restore them from the existing file they weremmap'd from. (The OS can detect which pages are unmodified by initially marking writablemmap'd pages as read only and catching seg faults, similar to Copy on Write strategy).
mmap 还可以优化操作系统分页。对于进程A、B,如果A通过 read 读取了1MB数据到buffer中,而B通过 mmap 读取1MB数据。如果OS想要把A中的 buffer 换入磁盘,首先要将buffer中的内容写入磁盘,才可以重用该物理页。而对于B中没有被修改过的 mmap 页,OS可以直接重用,因为OS可以从文件中再重新读取该页来恢复数据。
那么,如果 mmap 比起 open(),read() 有这么多优点,为什么不用 mmap 呢?对于系统来说,有优点往往意味着存在对应的缺点,这才是系统设计中的trade off。
mmap的缺点
- mmap 每次以页为单位从文件中读取数据,因此映射的页面大小始终是整数。对于小文件可能会造成较多的内部碎片。同时,在读取数据时也需要显式修正数据在页面中的偏移量。
- mmap 需要连续的虚拟内存空间用于储存文件,如果文件较大,对于32位地址空间的系统来说,可能找不到足够大的连续区域。
- mmap 本身开销比 read 大,因为mmap涉及更多的系统调用,需要触发缺页中断,更改虚拟内存映射。
总结
由于read 读取文件更加直观和易于理解,因此初学者依然使用 read 较多。但如果需要随机访问数据,或者和其他进程共享数据,用 mmap 不失为一个更好的选择。
什么时候选择mmap而非read?的更多相关文章
- Web前端开发:为何选择MVVM而非MVC
在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的技术原因,MVC在Web前端开发中根本无法使用(对的,是无法,而不是不该) 在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的 ...
- 【转】Web前端开发:为何选择MVVM而非MVC
在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的技术原因,MVC在Web前端开发中根本无法使用(对的,是无法,而不是不该) 在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的 ...
- jQuery获取Select选择的Text(非表单元素)和 Value(表单元素)(转)
jQuery获取Select选择的Text和Value: 语法解释: . $("#select_id").change(function(){//code...}); //为Sel ...
- 页面中的radio选择适合的非空判断
var cyjb=$('input:radio[name="jcrwModel.cyjb"]:checked').val(); if(cyjb==n ...
- (转)PHP线程安全与非线程安全的区别:如何选择用哪一个?
PHP线程安全与非线程安全的区别:如何选择用哪一个? 很多时候,我们在做PHP环境配置的时候,很多人都是直接去乱下载PHP版本的,但是他不清楚:从2000年10月20日发布的第一个Windows版的P ...
- mmap映射区和shm共享内存的区别总结
[转载]原文链接:https://blog.csdn.net/hj605635529/article/details/73163513 linux中的两种共享内存.一种是我们的IPC通信System ...
- Html5 简单选择排序演示
简单选择排序,是选择排序算法的一种.基本思想:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止.由于在每次循环中,会对数值相等的元素改变位置,所以属于非稳定 ...
- Jquery 系列(2) 选择元素
Jquery基础学习 jQuery利用css选择符的能力,能够在DOM中快捷而轻松地获取元素. 主要内容如下: 介绍DOM树 如何通过CSS选择符在页中查找元素 扩展jQuery标准的CSS选择符 选 ...
- ORACLE RAC 下非缺省端口监听配置(listener.ora tnsnames.ora)
不论是单实例还是RAC,对于非缺省端口下(1521)的监听器,pmon进程不会将service/instance注册到监听器,即不会实现动态注册.与单实例相同,RAC非缺省端口的监听器也是通过设置参数 ...
随机推荐
- 后端程序员之路 7、Zookeeper
Zookeeper是hadoop的一个子项目,提供分布式应用程序协调服务. Apache ZooKeeper - Homehttps://zookeeper.apache.org/ zookeeper ...
- AXU2CGB开发板验证Vitis加速基本平台创建
Vitis 加速基本平台创建 1.Vivado 工程创建,硬件平台bd 图如下所示 1.1.双击Block图中ZYNQ核,配置相关参数 1.1.1.Low Speed 配置,在 I/O Configu ...
- 一文了解python的 @property
参考自: https://www.programiz.com/python-programming/property Python为我们提供了一个内置装饰器@property,此方法使得getter和 ...
- 《C++ Primer》笔记 第6章 函数
任意两个形参都不能同名,而且函数最外层作用域中的局部变量也不能使用与函数形参一样的名字(形参就相当于该函数的局部变量). 形参名是可选的,但是由于我们无法使用未命名的形参,所以形参一般都应该有个名字. ...
- 剑指 Offer 46. 把数字翻译成字符串 + 动态规划
剑指 Offer 46. 把数字翻译成字符串 Offer_46 题目描述 题解分析 本题的解题思路是使用动态规划,首先得出递推公式如下 dp[i] = dp[i-1]+dp[i-2](如果s[i-1] ...
- 将samba共享目录映射为本地文件夹(百度网盘直接下载到samba共享目录下)
将samba共享目录映射为本地文件夹(百度网盘直接下载到samba共享目录下) 前面淘了一个蜗牛星际的矿机,打算拿来做个个人云盘,就装上了Linux用smb把硬盘共享出来 访问倒是很爽,就是发现下东西 ...
- WPF 基础 - 在模板中找元素
1. 在 ControlTemplate 中寻找元素 <Window.Resources> <ControlTemplate x:Key="cTmp"> & ...
- 基于renren-fast的快速入门项目实战(实现报表增删改查)
基于renren-fast的快速入门项目实战(实现报表增删改查) 说明:renren-fast是一个开源的基于springboot的前后端分离手脚架,当前版本是3.0 官方开发文档需付费,对于新手而言 ...
- POJ_2533 Longest Ordered Subsequence 【LIS】
一.题目 Longest Ordered Subsequence 二.分析 动态规划里的经典问题.重在DP思维. 如果用最原始的DP思想做,状态转移方程为$DP[i] = max(DP[j] + 1) ...
- Genymotion下载模拟器慢
•问题来源 Genymotion 是个很不错的 Android 模拟器,系统更新快,启动速度快: 但是服务器在国外,Android 镜像下载起来那个速度就不敢恭维了: 当然如果你可以[科学,上网]就另 ...