LINUX 中的mmap浅析

一、mmap基本原理和分类

在LINUX中我们可以使用mmap用来在进程虚拟地址空间中分配创建一片虚拟内存地址映射

其可以是

1、文件映射

使用文件内容初始化内存

2、匿名映射

初始化全为0的内存空间(calloc也可以)

下面配图来自UNIX系统编程手册

而对于是否共享又分为

1、私有映射(MAP_PRIVATE)

多进程间数据共享,修改不反应到磁盘实际文件,

私有写时复制实现

2、共享映射(MAP_SHARED)

多进程间数据共享,修改反应到磁盘实际文件中。

那么总结起来有4种组合

1、私有文件映射

多个进程使用同样的物理内存页进行初始化,但是各个进程

对内存文件的修改不会共享,也不会反应到物理文件中,比如

我们LINUX .so动态库文件就采用这种方式映射到各个进程虚拟

地址空间中

2、私有匿名映射

mmap会创建一个新的映射,各个进程不共享,这种使用主要用于

分配内存(malloc分配大内存会调用mmap)。

3、共享文件映射

多个进程通过虚拟内存技术共享同样的物理内存空间,对内存文件

的修改会反应到实际物理文件中,他也是进程间通信(IPC)的一种机制

4、共享匿名映射

这种机制在进行fork的时候不会采用写时复制,父子进程完全共享

同样的物理内存页,这也就实现了父子进程通信(IPC).

下面也是UNIX系统编程手册截图

在/proc/PID/maps下我们可以找到一个当前进程使用mmap创建的映射比如:

379a000000-379a016000 r-xp 00000000 08:03 12320771                       /lib64/libgcc_s-4.4.7-20120601.so.1

379a016000-379a215000 ---p 00016000 08:03 12320771                       /lib64/libgcc_s-4.4.7-20120601.so.1

379a215000-379a216000 rw-p 00015000 08:03 12320771                       /lib64/libgcc_s-4.4.7-20120601.so.1

379a400000-379a4e8000 r-xp 00000000 08:03 9700201                        /usr/lib64/libstdc++.so.6.0.13

379a4e8000-379a6e8000 ---p 000e8000 08:03 9700201                        /usr/lib64/libstdc++.so.6.0.13

379a6e8000-379a6ef000 r--p 000e8000 08:03 9700201                        /usr/lib64/libstdc++.so.6.0.13

379a6ef000-379a6f1000 rw-p 000ef000 08:03 9700201                        /usr/lib64/libstdc++.so.6.0.13

对于解释可以参考UNIX系统编程手册如下描述

二、mmap函数原型

void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

参数有点多

addr:映射放到哪里(虚拟地址),一般传NULL,让内核自己决定

length:映射的大小(直接),最小是系统页的整数倍(4K)

port:位图掩码

PROT_NONE   不能访问

PROT_READ   可读取

PROT_WRITE  可修改

PROT_EXEC   可执行

非法访问或报SIGSEGV段错误信号

flags:位图掩码

MAP_ANONYMOUS:创建一个匿名映射

MAP_PRIVATE:私有映射

MAP_SHARED:共享映射(注意并不能保证一定实际写入物理磁盘(MSYNC))

MAP_FIXED:addr必须是页对齐地址

其他标示不做解释

fd:映射文件的文件描述符

offset:从文件的哪个位置开始映射,必须是系统页的整数倍(4K)

返回值:

成功返回映射的虚拟内存地址的起始地址,失败返回MAP_FAILED

三、建立匿名映射

1、指针MAP_ANONYMOUS,并且fd指定为0

2、打开/dev/zero文件将文件描述符传递给mmap()

匿名映射会分配初始化全为0的虚拟内存空间

四、其他函数

int msync(void *addr, size_t length, int flags);

用于将kener buffer的数据同步到磁盘

int munmap(void *addr, size_t length);

用于解除映射

五、程序实例

下面我们通过mmap做私有匿名映射来完成一个小的线程间同步问题程序,用这片

内存区域来做线程间通信

点击(此处)折叠或打开#include

#include

#include

#include

#define uint unsigned int

#define MMSIZE (uint)(1<<23)

#define MSIZE (uint)(1<<20)

#define MPRT (uint)(1<<16)

using namespace std;

class tc

{

private:

uint a;

public:

tc():a(1)

{

;

}

~tc()

{

;

}

void add()

{

a=a+1;

}

void set()

{

a=1;

}

void prt(int i)

{

if(!(i%(MPRT)))

{

cout<

}

}

};

struct tt

{

tc* p1;

pthread_mutex_t* p2;

};

void* test(void* arg)

{

int i = 0;

tt* s = NULL;

s = (tt*)arg;

int maxloop = 50;

while(maxloop--)

{

i = MSIZE;

pthread_mutex_lock(s->p2);//MUTEX保护临界区

cout<

for(;i--;)

{

(s->p1+i)->prt(i);

(s->p1+i)->add();

}

cout<

pthread_mutex_unlock(s->p2);//解锁

}

}

int main(void)

{

pthread_t tid[3];

pthread_mutex_t pmut;

tt s1;

tc* p = (tc*)mmap(NULL,MMSIZE,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,-1,0);//MMAP分配一个匿名私有虚拟内存用于线程间通信

pthread_mutex_init(&pmut,NULL);

s1.p1 = p;

s1.p2 = &pmut;

int i = MSIZE+1;

for(;i--;)

{

(p+i)->set();//初始化所有的a=1

}

for(i=0;i<3;i++)

{

pthread_create(tid+i,NULL,test,(void*)&s1);//建立3个线程

}

for(i = 0;i<3;i++)

{

pthread_join( *(tid+i) , NULL);//堵塞回收线程

}

pthread_mutex_destroy(&pmut);

munmap(p,MMSIZE);

}

同时我们也观察到了线程由于失去CPU而放弃执行其他线程得到CPU继续执行,由于

我们使用MUTEX保护临界区这个数数还是正常进行。最后正常数到了150

Thread:140545405572864 work now!!!

:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32:32

Thread:140545397180160 work now!!! (线程140545405572864 失去CPU线程140545397180160执行)

:33:33:33:33:33:33:33:33:33:33:33:33:33:33:33:33

..................

Thread:140545397180160 work now!!!

:58:58:58:58:58:58:58:58:58:58:58:58:58:58:58:58

Thread:140545405572864 work now!!!(线程140545405572864重新获得CPU)

:59:59:59:59:59:59:59:59:59:59:59:59:59:59:59:59

............

Thread:140545388787456 work now!!!

:150:150:150:150:150:150:150:150:150:150:150:150:150:150:150:150

linux mmap 作用,LINUX 中的mmap浅析相关推荐

  1. linux dm 作用,Linux dm中minor number的管理——idr

    1. idr机制 Linux的dm中对minor number采用idr机制进行管理.idr即"ID Radix",内核中通过radix树对ID进行组织和管理,是一种将整数ID和指 ...

  2. linux poll 作用,Linux中poll机制的理解

    首先分析下应用程序的执行过程: int main(int argc, char **argv) { int fd; unsigned char key_val; int ret; struct pol ...

  3. Linux locate 作用,linux中的locate命令的详细解释

    linxu下的locate命令可以在搜寻数据库时快速找到档案,是个很方便的命令.下面由学习啦小编为大家整理了linux的locate命令的详细解释的相关知识,希望对大家有帮助! 一.linux中的lo ...

  4. linux tmpfs作用,linux ramfs和tmpfs区别及用法介绍

    ramfs是Linux下一种基于RAM做存储的文件系统.在使用过程中你就可以把ramfs理解为在普通的HDD上建立了一个文件系统,而现在HDD被替换成了RAM,因为是RAM做存储所以会有很高的存储效率 ...

  5. linux strip作用,linux gcc strip命令简介

    阅读目录 strip简介 strip经常用来去除目标文件中的一些符号表.调试符号表信息,以减小静态库.动态库和程序的大小. strip支持的选项可通过如下命令查看: strip --help stri ...

  6. linux 正则表达式 作用,Linux 正则表达式使用简介

    正则表达式基本介绍 正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则的字符串.在很多文本编辑里,正则表达式通常被用来检索.替换那些符合某个模式的文本. 正则表达式的基本元素包括普通字符和元字 ...

  7. linux acpi 作用,Linux ACPI服务ACPI 驱动体系简介

    Linux ACPI服务DSDT: DSDT 称做 Differentiated Definition Block,存在于 BIOS 中并与当前的硬件平台兼容的,提供了系统的硬件特性(例如某些设备的内 ...

  8. linux tmpfs作用,Linux下tmpfs介绍与使用

    1 Tmpfs是什么 tmpfs是Linux/Unix系统上的一种基于内存的文件系统.tmpfs可以使用您的内存或swap分区来存储文件.由此可见,tmpfs主要存储 暂存的文件. 优势 : 1. 动 ...

  9. linux文件目录作用,linux 文件目录,及其作用

    /boot:系统启动相关的相关文件,如内核,initrd,以及grub(bootloader) /dev: 设备文件 设备文件: 块设备:随机访问,数据块 字符设备:线性访问,按字符文单位 设备号:主 ...

  10. linux dup作用,linux dup()\dup2()函数

    dup函数的作用:复制一个现有的句柄,产生一个与"源句柄特性"完全一样的新句柄(也即生成一个新的句柄号,并关联到同一个设备) dup2函数的作用:复制一个现有的句柄到另一个句柄上, ...

最新文章

  1. 原子核与外围电子有非常大的空间为什么物体有光滑的平面
  2. 越小越好:为什么电子器件都这么小巧玲珑?
  3. 选择ButterKnife,告别findViewById
  4. strtus2改成springboot_jdk1.6环境下struts2改spring boot方案-阿里云开发者社区
  5. idea怎么搜索文件——search everywhere
  6. 新浪微博数据网络舆情分析客户端软件
  7. math库是python语言的数学模块_Python 数学模块(Math)
  8. 图解linux32位平台下进程线程长什么样子
  9. 微信分享签名无效php_php实现微信分享朋友链接功能
  10. 10年10亿才能烧好电子商务?
  11. ubuntu安装jdk
  12. 程序员如何用六年时间打造价值10亿的帝国?
  13. Linux 的 复制命令 【 cp 】 (copy)及其 (常用参数 -fp)
  14. Java开发 音视频会议
  15. 华为USG6000V防火墙telnet+安全策略
  16. 荣誉加持,驭势科技近期斩获奖项回顾
  17. 拓扑排序 POJ - 3687反向图跑字典序(重边)
  18. Springboot企业工资管理rycxe计算机毕业设计-课程设计-期末作业-毕设程序代做
  19. left join 和 left outer join (可解决多个表left join的问题)
  20. Java职责链模式详解

热门文章

  1. int转byte数组以及相关原理
  2. AOSP 隐藏 su
  3. ireport 3.6.0 增加PDF字体、加粗失效、PDF中文不显示等问题
  4. LeetCode——75. 颜色分类(面试题)
  5. 解决Mac无法识别移动硬盘以及无法识别BootCamp Windows分区的问题
  6. win10浏览器闪退_win10自带浏览器闪退解决方法
  7. jquery实现侧边栏手风琴三级导航菜单demo
  8. 深度学习教程(14) | 序列模型与RNN网络(吴恩达·完整版)
  9. Android应用帧率--FPS测试
  10. 米家扫地机器人是石头代工_石头扫地机器人T4全面评测 支持软件虚拟墙,清扫更高效...