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 ,有如下优势:

  1. 对于随机访问,不用频繁 lseek。因为 mmap 是将整个文件映射到虚拟空间,在读取时再按需分配物理内存。
  2. 减少后续系统调用次数。后续读文件时不需要再进入内核态,减少了上下文切换
  3. 减少数据拷贝。免去了page cache 到 buffer 的数据拷贝。
  4. 当多个进程将同一页面映射到内存时,数据可以在这些进程之间共享。对于 只读 的页面可以完全共享,需要写入的文件可以使用COW(copy on write)私有化。这样节省了大量内存。

mmap also allows the operating system to optimize paging operations. For example, consider two programs; program A which reads in a 1MB file into a buffer creating with malloc, and program B which mmaps the 1MB file into memory. If the operating system has to swap part of A's memory out, it must write the contents of the buffer to swap before it can reuse the memory. In B's case any unmodified mmap'd pages can be reused immediately because the OS knows how to restore them from the existing file they were mmap'd from. (The OS can detect which pages are unmodified by initially marking writable mmap'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的缺点

  1. mmap 每次以页为单位从文件中读取数据,因此映射的页面大小始终是整数。对于小文件可能会造成较多的内部碎片。同时,在读取数据时也需要显式修正数据在页面中的偏移量。
  2. mmap 需要连续的虚拟内存空间用于储存文件,如果文件较大,对于32位地址空间的系统来说,可能找不到足够大的连续区域。
  3. mmap 本身开销比 read 大,因为mmap涉及更多的系统调用,需要触发缺页中断,更改虚拟内存映射。

总结

由于read 读取文件更加直观和易于理解,因此初学者依然使用 read 较多。但如果需要随机访问数据,或者和其他进程共享数据,用 mmap 不失为一个更好的选择。

什么时候选择mmap而非read?的更多相关文章

  1. Web前端开发:为何选择MVVM而非MVC

    在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的技术原因,MVC在Web前端开发中根本无法使用(对的,是无法,而不是不该) 在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的 ...

  2. 【转】Web前端开发:为何选择MVVM而非MVC

    在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的技术原因,MVC在Web前端开发中根本无法使用(对的,是无法,而不是不该) 在Web中充斥着所谓的MVC框架,而在我看来,因为一些关键性的 ...

  3. jQuery获取Select选择的Text(非表单元素)和 Value(表单元素)(转)

    jQuery获取Select选择的Text和Value: 语法解释: . $("#select_id").change(function(){//code...}); //为Sel ...

  4. 页面中的radio选择适合的非空判断

     var cyjb=$('input:radio[name="jcrwModel.cyjb"]:checked').val();                if(cyjb==n ...

  5. (转)PHP线程安全与非线程安全的区别:如何选择用哪一个?

    PHP线程安全与非线程安全的区别:如何选择用哪一个? 很多时候,我们在做PHP环境配置的时候,很多人都是直接去乱下载PHP版本的,但是他不清楚:从2000年10月20日发布的第一个Windows版的P ...

  6. mmap映射区和shm共享内存的区别总结

    [转载]原文链接:https://blog.csdn.net/hj605635529/article/details/73163513 linux中的两种共享内存.一种是我们的IPC通信System ...

  7. Html5 简单选择排序演示

    简单选择排序,是选择排序算法的一种.基本思想:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止.由于在每次循环中,会对数值相等的元素改变位置,所以属于非稳定 ...

  8. Jquery 系列(2) 选择元素

    Jquery基础学习 jQuery利用css选择符的能力,能够在DOM中快捷而轻松地获取元素. 主要内容如下: 介绍DOM树 如何通过CSS选择符在页中查找元素 扩展jQuery标准的CSS选择符 选 ...

  9. ORACLE RAC 下非缺省端口监听配置(listener.ora tnsnames.ora)

    不论是单实例还是RAC,对于非缺省端口下(1521)的监听器,pmon进程不会将service/instance注册到监听器,即不会实现动态注册.与单实例相同,RAC非缺省端口的监听器也是通过设置参数 ...

随机推荐

  1. 力扣208. 实现 Trie (前缀树)

    原题 以下是我的代码,就是简单的字符串操作,可以ac但背离了题意,我之前没接触过Trie 1 class Trie: 2 3 def __init__(self): 4 ""&qu ...

  2. Java实现文件的读写

    需求:实现基本的读写 package com.sbx.io; import java.io.File; import java.io.FileReader; import java.io.FileWr ...

  3. 话说 synchronized

    一.前言 ​ 说起java的锁呀,我们先想到的肯定是synchronized[ˈsɪŋ krə naɪ zd]了 ,这个单词很拗口,会读这个单词在以后的面试中很加分(我面试过一些人 不会读 ,他们说的 ...

  4. PAT-1148(Werewolf )思维+数学问题

    Werewolf PAT-1148 题目的要点是不管n规模多大,始终只有两个狼人 说谎的是一个狼人和一个好人 紧紧抓住这两点进行实现和分析 #include <iostream> #inc ...

  5. 翻译:《实用的Python编程》03_05_Main_module

    目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论) 3.5 主模块 本节介绍主程序(主模块)的概念 主函数 在许多编程语言中,存在一个主函数或者主方法的概念. // c / c++ ...

  6. Java入门和环境配置ideaJ安装

    Java入门及环境搭建 目录 Java入门及环境搭建 什么是Java Java Java的发展 Java的特性和优势 Java三大版本 JDK JRE JVM JAVA开发环境搭建 安装JDK 卸载J ...

  7. 安卓Media相关类测试demo

    最近在研究安卓系统给app开发者提供的标准Media相关的工具类,本人做了一些demo来测试这些工具的使用方法. 本demo包含若干apk源码,需要说明以下几点: 1. 构建方式 Makefile使用 ...

  8. Java视频教程免费分享(网盘直接取)

    Java基础 Java马士兵:链接:https://pan.baidu.com/s/1jJRvxGi密码:v3xb Java刘意:链接:https://pan.baidu.com/s/1kVZQCqr ...

  9. 叫练手把手教你读JVM之GC信息

    案例 众所周知,GC主要回收的是堆内存,堆内存中包含年轻代和老年代,年轻代分为Eden和Surivor,如下图所示.我们用案例分析下堆的GC信息[版本:HotSpot JDK1.8]. /** * @ ...

  10. Linux入门视频笔记一(基本命令)

    一.简单命令 1.date:当前时间 2.cal:当前日期(日历格式) ①cal 2019:2019年全年日历 ②cal 1 2019:2019年1月份 二.Linux文件结构 1.根目录:root( ...