本文写于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. Drools+springboot

    查看我的github, 后续会陆续补充文档和Drools技术 https://github.com/zongheng14/insurance-rules

  2. 【python3】 函数 装饰器

    第一步 : 了解装饰器 装饰器模式,重点在于装饰,装饰的核心仍是被装饰的对象. 举一个栗子:我今天穿了一件短袖,但是突然一阵风,短袖没办法为我御寒,我想到的办法是将短袖变得更厚更长,但是改造之后,它就 ...

  3. P2822 组合数问题

    传送门 思路: 利用公式: C( n,r ) = C( n-1,r ) + C( n-1,r-1 ) 由此可以将计算 C( n,r ) 的过程化为加法来做. 可以看出,C( n,r ) 其实就是求杨辉 ...

  4. Foxmail设置IMAP和STMP服务器

  5. 02-VC中的变量类型

    lp: long pointerb: BOOLsz: string zero(以0结尾的字符串) typedef const char* LPCSTRtypedef unsigned long DWO ...

  6. spring 事务关键类

    TransactionInterceptor-> TransactionAspectSupport spring 事务的提交 AbstractPlatformTransactionManager

  7. 【Code Tools】Java微基准测试工具JMH之中级篇

    一.JMH中的基本概念 1)Mode Mode 表示 JMH 进行 Benchmark 时所使用的模式.通常是测量的维度不同,或是测量的方式不同.目前 JMH 共有四种模式: 1.Throughput ...

  8. QT 右键弹出菜单

    QWidget及其子类都可有右键菜单 1.设置标志 在widget初始化的时候 setContextMenuPolicy(Qt::CustomContextMenu); 设置为自定义菜单模式 2.在需 ...

  9. 'ascii' codec can't decode byte 0xe5 in position 10: ordinal not in range(128)

    python2.7 向Excel中写入数据中含有中文就一直报错 'ascii' codec can't decode byte 0xe5 in position 10: ordinal not in ...

  10. vue 渲染后更新数据

    this.$set(this.selGetData,level,[{},{}])this.$set(this.selGetData,1,{message:"Test add attr&quo ...