本文写于2017-03-11,从老账号迁移到本账号,原文地址:https://www.cnblogs.com/huangweiyang/p/6534877.html

概述

mmap()系统调用在调用进程的虚拟地址空间中创建一个新的内存映射。munmap()系统调用执行逆操作,即从进程的地址空间删除一个映射。

映射可以分为两种:基于文件的映射和匿名映射。文件映射将一个文件区域中的内容映射到进程的虚拟地址空间中。匿名映射(通过使用MAP_ANONYMOUS)标记或映射/dev/zero来创建)并没有对应的文件区域,该映射中的字节会被初始化为0。

映射既可以是私有的(MAP_PRIVATE),也可以是共享的(MAP_SHARED)。这种差别确定了在共享内存上发生的变更的可见性,对于文件映射来讲,这种差别还确定了内核是否会将映射内容上发生的变更传递到底层文件上。当一个进程使用MAP_PAIVATE映射一个文件之后,在映射内容上发生的变更对其他进程是不可见的,并且也不会反应到映射文件上。MAP_SHARED文件映射的做法则相反——在映射上发生的变更对其他进程可见并且会反应到映射文件上。

尽管内核会自动地将发生在一个MAP_SHARED映射内容上的变更反应到底层文件上(pdflush线程),但它不保证合适完成这个操作。应用程序可以使用msync()系统调用来显示地控制一个映射内容何时与映射文件进行同步。

内存映射有多种用途:

  1. 分配进程私有的内存(私有匿名映射)
  2. 对一个进程的文本段和初始化数据段中的内容进行初始化(私有文件映射)
  3. 在通过fork()关联起来的进程之间共享内存(共享匿名映射)
  4. 执行内存映射I/O,还可以将其与无关简称之间的内存共享结合起来(共享文件映射)

在访问一个映射的内容时可能会遇到两个信号。如果在访问映射时违反了映射之上的保护规则(或访问一个当前未被映射的地址),那么就会产生一个SIGSEGV信号。对于基于文件的映射来讲,如果访问的映射部分在文件中没有相关区域与之对应(即映射大于底层文件,但仍算映射了,而不是未映射),那么就会产生一个SIGBUS信号。

交换空间过度利用允许系统给进程分配比实际可用的RAM与交换空间之和更多的内存。过度利用之所以可能是因为所有进程都不会全部用完为其分配的内存。使用MAP_NORESERVE标记可以控制每个mmap()调用的过度利用情况,而是用/proc文件则可以控制整个系统的过度利用情况。

mremap()系统调用允许调整一个既有映射的大小。remap_file_pages()系统调用允许创建非线性文件映射。

对于mmap()映射文件和read()文件来说,read()在读次数少的情况下比mmap()快。因为虽然mmap()不需要read()的那一次内存拷贝,但是硬件的发展,使得内存拷贝消耗时间极大降低了。而且mmap()的开销在于缺页中断,处理任务比较多。并且,mmap之后,再有读操作不会经过系统调用,所以在LRU比较最近使用的页时并不占优势,容易被换出内存。所以,普通读的情况下(排除反复读),read()通常比mmap()来得更快。

关于mmap,这里有一张图挺有意思的:mmap 文件映射内存详解

mmap共享内存深入总结的更多相关文章

  1. Linux下多任务间通信和同步-mmap共享内存

    Linux下多任务间通信和同步-mmap共享内存 嵌入式开发交流群280352802,欢迎加入! 1.简介 共享内存可以说是最有用的进程间通信方式.两个不用的进程共享内存的意思是:同一块物理内存被映射 ...

  2. mmap和shm共享内存的区别和联系

    共享内存的创建 根据理论: 1. 共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制.共享内存可以通过mmap()映射普通文件(特殊情况下还可以采用匿 ...

  3. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  4. 内存分配的原理__进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)

    如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...

  5. 进程间通信之信号量、消息队列、共享内存(system v的shm和mmap)+信号signal

    进程间通信方式有:System v unix提供3种进程间通信IPC:信号量.消息队列.共享内存.此外,传统方法:信号.管道.socket套接字. [注意上述6种方式只能用户层进程间通信.内核内部有类 ...

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

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

  7. 使用mmap可以方便地添加共享内存

    使用mmap添加的共享内存. 局限: 只能在有亲属关系的进程之间使用. #include <stdio.h> #include <stdlib.h> #include < ...

  8. 共享内存:mmap函数实现

    内存映射的应用: 以页面为单位,将一个普通文件映射到内存中,通常在须要对文件进行频繁读写时使用,这样用内存读写代替I/O读写,以获得较高的性能; 将特殊文件进行匿名内存映射,能够为关联进程提供共享内存 ...

  9. mmap映射文件至内存( 实现 共享内存 与 文件的另类访问 )

    Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明: 头文件: < ...

随机推荐

  1. Mac在Finder中显示隐藏文件

    1.显示隐藏文件 打开终端,输入下面的命令: defaults write com.apple.finder AppleShowAllFiles -bool true KillAll Finder   ...

  2. Java基础学习-标识符

    1.标识符的作用     -给包.类.方法.变量等起名字 2.组成规则     -这里的字符采用的是Unicode字符集,所以包括英文大小写字母,中文字符,数字字符等.不建议使用汉字.     -下划 ...

  3. msql事务与引擎

    事务介绍   简单来说,事务就是指逻辑上的一组SQL语句操作,组成这组操作的各个SQL语句,执行时要么全成功要么全失败.    MySQL5.5支持事务的引擎:Innodb/ndb  一.事务四大特性 ...

  4. Typora 和 markdown

    目录 Typora 和 markdown Typora 简单介绍 markdown语法 导出 Typora 和 markdown Typora 简单介绍 支持markdown的一款优雅的编辑器. 绿色 ...

  5. WEB API系列(一):WEB API的适用场景、第一个实例

    在我前一篇博客中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下,今天,我们一起来讨论一下WEB API的适用场景,然后写我们第一个W ...

  6. Vue-admin工作整理(十四):Vuex和双向绑定

    概述,普通的直接通过input修改值然后取是不符合vue的规格的,所有数据定义和传递必须通过actions或者mutation来做 思路:通过在mutation层对字段进行定义值,在store中通过v ...

  7. Spring定时任务@Scheduled注解使用方式

    1.开篇 spring的@Scheduled定时任务相信大家都是十分熟悉.最近在使用过程中发现了一些问题,写篇文章,和大家分享一下.结论在最后,不想看冗长过程的小伙伴可以直接拉到最后看结论. 2.简单 ...

  8. git删除文件夹

    git  rm  要删除的文件夹  -r -f   git  commit  -m  'del  config' git  push 使用场景,删除test文件夹,本来在码云上,正常的文件夹右击会出现 ...

  9. R语言查看栅格值

    有这么一个需求,知道栅格上的坐标,想看看这个坐标上的栅格值是多少.坐标长这个样子 那么这样的坐标下的栅格值该怎么看 cellFromXY(the.stack$t1,c( -1505000,683500 ...

  10. MySQL优化查询 5.7版本

    1. 变更参数 : query_cache_type 如果何配置查询缓存: query_cache_type 这个系统变量控制着查询缓存工能的开启的关闭.query_cache_type=0时表示关闭 ...