很多文章分析了mmap的实现原理。从代码的逻辑来分析,总是觉没有把mmap后读写映射区域和普通的read/write联系起来。不得不产生疑问:

1,普通的read/write和mmap后的映射区域的读写到底有什么区别。

2, 为什么有时候会选择mmap而放弃普通的read/write。

3,如果文章中的内容有不对是或者是不妥的地方,欢迎大家指正。

围绕着这两个问题分析一下,其实在考虑这些问题的同时不免和其他的很多系统机制产生交互。虽然是讲解mmap,但是很多知识还是为了阐明问题做必要的铺垫。这些知识也正是Linux的繁琐所在。一个应用往往和系统中的多种机制交互。这篇文章中尽量减少对源代码的引用和分析。把这样的工作留到以后的细节分析中。但是很多分析的理论依据还是来自于源代码。可见源代码的重要地位。

基础知识:

1, 进程每次切换后,都会在tlb base寄存器中重新load属于每一个进程自己的地址转换基地址。在cpu当前运行的进程中都会有current宏来表示当前的进程的信息。应为这个代码实现涉及到硬件架构的问题,为了避免差异的存在在文章中用到硬件知识的时候还是指明是x86的架构,毕竟x86的资料和分析的研究人员也比较多。其实arm还有其他类似的RISC的芯片,只要有mmu支持的,都会有类似的基地址寄存器。

2, 在系统运行进程之前都会为每一个进程分配属于它自己的运行空间。并且这个空间的有效性依赖于tlb base中的内容。32位的系统中访问的空间大小为4G。在这个空间中进程是“自由”的。所谓“自由”不是说对于4G的任何一个地址或者一段空间都可以访问。如果要访问,还是要遵循地址有效性,就是tlb base中所指向的任何页表转换后的物理地址。其中的有效性有越界,权限等等检查。

3, 任何一个用户进程的运行在系统分配的空间中。这个空间可以有

vma:struct vm_area_struct来表示。所有的运行空间可以有这个结构体描述。用户进程可以分为text data 段。这些段的具体在4G中的位置有不同的vma来描述。Vma的管理又有其他机制保证,这些机制涉及到了算法和物理内存管理等。请看一下两个图片:

图 一:

图 二:

系统调用中的write和read:

这里没有指定确切的文件系统类型作为分析的对象。找到系统调用号,然后确定具体的文件系统所带的file operation。在特定的file operation中有属于每一种文件系统自己的操作函数集合。其中就有read和write。

图 三:

在真正的把用户数据读写到磁盘或者是存储设备前,内核还会在page cache中管理这些数据。这些page的存在有效的管理了用户数据和读写的效率。用户数据不是直接来自于应用层,读(read)或者是写入(write)磁盘和存储介质,而是被一层一层的应用所划分,在每一层次中都会有不同的功能对应。最后发生交互时,在最恰当的时机触发磁盘的操作,通过IO驱动写入磁盘和存储介质。这里主要强调page cache的管理。应为page的管理设计到了缓存,这些缓存以page的单位管理。在没有IO操作之前,暂时存放在系统空间中,而并未直接写入磁盘或者存贮介质。

系统调用中的mmap:

当创建一个或者切换一个进程的同时,会把属于这个当前进程的系统信息载入。这些系统信息中包含了当前进程的运行空间。当用户程序调用mmap后。函数会在当前进程的空间中找到适合的vma来描述自己将要映射的区域。这个区域的作用就是将mmap函数中文件描述符所指向的具体文件中内容映射过来。

原理是:mmap的执行,仅仅是在内核中建立了文件与虚拟内存空间的对应关系。用户访问这些虚拟内存空间时,页面表里面是没有这些空间的表项的。当用户程序试图访问这些映射的空间时,于是产生缺页异常。内核捕捉这些异常,逐渐将文件载入。所谓的载入过程,具体的操作就是read和write在管理pagecache。Vma的结构体中有很文件操作集。vma操作集中会有自己关于page cache的操作集合。这样,虽然是两种不同的系统调用,由于操作和调用触发的路径不同。但是最后还是落实到了page cache的管理。实现了文件内容的操作。

Ps:

文件的page cache管理也是很好的内容。涉及到了address space的操作。其中很多的内容和文件操作相关。

效率对比:

这里应用了网上一篇文章。发现较好的分析,着这里引用一下。

Mmap:

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

#include <sys/mman.h>

void main()

{

int fd = open("test.file", 0);

struct stat statbuf;

char *start;

char buf[2] = {0};

int ret = 0;

fstat(fd, &statbuf);

start = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

do {

*buf = start[ret++];

}while(ret < statbuf.st_size);

}

Read:

#include <stdio.h>

#include <stdlib.h>

void main()

{

FILE *pf = fopen("test.file", "r");

char buf[2] = {0};

int ret = 0;

do {

ret = fread(buf, 1, 1, pf);

}while(ret);

}

运行结果:

[xiangy@compiling-server test_read]$ time ./fread

real    0m0.901s

user    0m0.892s

sys     0m0.010s

[xiangy@compiling-server test_read]$ time ./mmap

real    0m0.112s

user    0m0.106s

sys     0m0.006s

[xiangy@compiling-server test_read]$ time ./read

real    0m15.549s

user    0m3.933s

sys     0m11.566s

[xiangy@compiling-server test_read]$ ll test.file

-rw-r--r-- 1 xiangy svx8004 23955531 Sep 24 17:17 test.file

可以看出使用mmap后发现,系统调用所消耗的时间远远比普通的read少很多。

比较详细的解释: http://blog.csdn.net/yinjiabin/article/details/7575653

转载:http://blog.csdn.net/edwardlulinux/article/details/8604400

Mmap的实现原理和应用相关推荐

  1. mmap内存映射原理

    mmap概念 mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.  特点:实现这样的映射关系后,进程就可以 ...

  2. Linux内存管理子系统——mmap内存映射原理分析(dax文件系统的mmap)

    Linux mmap分析 内核版本:linux-5.16 1. 虚拟内存概要及相关内容简介 内存映射是学习过操作系统的大家都耳熟能详的词,理解起来也很简单.所谓"映射"就是为一种事 ...

  3. igs无法分配驱动器映射表_Linux的mmap内存映射原理到底是怎样的?

    在Unix/Linux系统下读写文件,一般有两种方式. 一种是open一个文件,然后使用read系统调用读取文件的一部分或全部.这个read过程是这样的:内核将文件中的数据从磁盘区域读取到内核页高速缓 ...

  4. linux+mmap父子通信_linux库函数mmap()原理?转载

    linux库函数mmap()原理 转载 1.mmap基本概念 2.mmap内存映射原理 3.mmap和常规文件操作的区别 4.mmap优点总结 5.mmap相关函数 6.mmap使用细节 7.mmap ...

  5. linux库函数mmap()原理及用法详解

    目录 1.mmap基本概念 2.mmap内存映射原理 3.mmap和常规文件操作的区别 4.mmap优点总结 目录 1. 内存映射的概念 2. mmap基本概念 3. mmap相关函数 3.2 参数说 ...

  6. Android 进程间通信机制(二) mmap 原理

    一. 前言 Binder中一次拷贝的实现就是利用mmap(memory mapping)内存映射机制,我们来看看它的工作原理. 二. 参考文章 下面这几篇文章建议先好好阅读一下,都是总结的很好的文章, ...

  7. Linux mmap原理

    Linux mmap原理 前言 Linux段页式内存管理 mmap mmap内存映射原理 文字概述 mmap函数参数介绍 源码解析 1. 文件映射 2. 缺页异常 mmap 和常规文件操作的区别 mm ...

  8. Android MMKV使用及 MMAP原理

    什么是MMKV MMKV--基于 mmap 的高性能通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强. MMKV 是基于 mmap 内存映射的移动端通 ...

  9. linux存储--共享内存机制mmap(十二)

    mmap基础概念 mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.实现这样的映射关系后,进程就可以采用指 ...

  10. OS - MMAP初探

    文章目录 生猛干货 What's mmap mmap 函数 mmap() 的底层原理 虚拟内存空间与物理内存空间 vm_area_struct 结构 对文件的读写 搞定计算机基础内功 生猛干货 计算机 ...

最新文章

  1. sql语句中left join和inner join中的on与where的区别分析
  2. GD32如何替换STM32?
  3. javafx 加载_JavaFX 2:如何加载图像
  4. verilog学习记(verilog翻译成c)
  5. ubuntu 个人常用的命令
  6. 阵列信号处理及matlab实现_球形麦克风阵列设计
  7. 计算机极差全距符号,极差相对值的计算公式
  8. 通过代理服务器下载网页
  9. UE4编辑器界面语言切换
  10. Mysql从入门到入魔——8. 视图、存储过程、事务处理
  11. 《周一清晨的领导课》--司机与乘客 - [读书笔记]
  12. Android Studio真机测试
  13. html上图片用js绘制点,用 js + html 描图 与画箭头
  14. 论文阅读:Generating Abstractive Summaries with Finetuned Language Models
  15. 小程序 _ 学习笔记
  16. 【342期】SpringBoot + Redis 布隆过滤器防恶意流量击穿缓存的正确姿势!
  17. Kubernetes 固定 Pod IP 地址方法
  18. 机器学习和深度学习之数学基础-线性代数 第一节 向量及线性映射
  19. 网站进入前10名的需要的操作
  20. 大型网站系统与Java中间件实践 第二章大型网站及其架构演进过程

热门文章

  1. Excel数据导入到oracle
  2. 所闻所获3:下拉刷新控件1
  3. yii2添加自定义字段
  4. 远程调试云端php,Vim XDebug调试PHP php远程调试
  5. android开发歌词滑动效果_一些Flutter开发中的“坑”
  6. 如何创建PDF格式文件,这个方法教你快速创建
  7. sql 判断连续数字
  8. 菜鸟学Linux 第055篇笔记 php基础
  9. javascript--返回顶部效果
  10. vue的自定义指令的坑