函数简介

在Linux操作系统中,进程是资源分配的基本单位。所以说每个进程间有各自独立的存储空间,但是在某些情况下各进程要相互配合来完成特定任务,这样就使得进程间通信变得非常必要。进程间通信方式有多种,当然这不是我们这节要讨论的重点,这节主要说的是mmap函数,它是通过将一块物理内存映射到多个进程的虚拟地址空间上,来完成多个进程对同一块物理内存的读写从而使得进程间能够实现通信。

先看一下mmap函数的函数原型,如下:

参数说明:
                  addr:映射区的开始地址,设置为NULL时表示由系统决定映射区的起始地址。
                  length:映射区的长度。//长度单位是 以字节为单位,不足一内存页按一内存页处理
                  prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起
                            PROT_READ //页内容可以被读取
                            PROT_WRITE //页可以被写入
                  flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体
                            MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。
                            MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。
                            MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联,简写为:MAP_ANON。
                  fd:有效的文件描述词。
                  offset:被映射对象内容的偏移量(4K的整数倍)。

返回值说明:
                  成功执行时,mmap()返回被映射区的指针,返回MAP_FAILED(其值为(void *)-1)。

程序案例

案例一:进程通过fork函数产生子进程时,我们知道父进程除了打开的文件描述符被子进程共享外,还有就是父进程通过调用mmap函数产生的映射地址空间被父子进程共享。看一个案例如下:

/**************************************
作   者 : lijd
生成日期 : 2021年02月06日
功能描述 : mmap函数案例测试
**************************************/
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>int main(int argc,char **argv)
{int ret, inum = 0;
#if 0    // 该段用匿名映射区代替int fd = open("mytest.txt", O_CREAT|O_RDWR, 0644);if(fd < 0){perror("open feild!");return -1;}ret = ftruncate(fd, 4);if(ret == -1){perror("ftruncate feild!");return -1;}char *ptr = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if(ptr == MAP_FAILED){perror("mmap feild!");return -1;}close(fd);
#elsechar *ptr = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);if(ptr == MAP_FAILED){perror("mmap feild!");return -1;}
#endif*(int *)ptr = 1234;printf("ptr : %d, inum : %d\n", *(int *)ptr, inum);pid_t pid = fork();if(pid == 0)   // son {*(int *)ptr = 5678;inum = 6666;printf("ptr : %d, inum : %d\n", *(int *)ptr, inum);}if(pid > 0)   // father{wait(NULL);   printf("ptr : %d, inum : %d\n", *(int *)ptr, inum);ret = munmap(ptr, 4);if(ret == -1){perror("munmap feild!");return -1;}}return 0;
}

执行结果如下:

分析上图的执行结果:刚开始指针ptr指向的内存空间调用到mmap函数申请到空间后,父进程使其存储的值为:1234,而变量inum的值为0,当fork创建子进程后,在子进程总将指针ptr执行的内容值修改为:5678,变量inum的值变为6666。当子进程执行完毕后父进程中的指针ptr中的内容变成了子进程修改后的值,而变量inum还是之前的0。因为父子进程共享mmap函数创建的内存,而当子进程修改inum变量时子进程使用了写时拷贝技术,为inum变量重新申请了内存存放修改后的新值。

上述案例是父子进程间通信,若非血缘关系的进程间通信则只需调用mmap映射同一个文件,这里就不再赘述。

案例二:我们思考一下,若两个进程通过打开同一文件能不能进行通信呢?看下面一个案例:

进程1代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>int main(int argc,char **argv)
{int ret = 0;char buf[256] = {0};char *str = "-----------------lijd 1111---------------------\n";int fd = open("mytest.txt", O_CREAT|O_RDWR|O_TRUNC, 0644);write(fd, str, strlen(str));printf("test1 write mytest.txt finish!\n");lseek(fd, 0, SEEK_SET);sleep(10);ret = read(fd, buf, sizeof(buf));printf("mytest.txt : %s\n", buf);close(fd);return 0;
}

进程2代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>int main(int argc,char **argv)
{int ret = 0;char buf[256] = {0};char *str = "-----------------lijd 2222---------------------\n";int fd = open("mytest.txt", O_RDWR);   ret = read(fd, buf, sizeof(buf));printf("mytest.txt : %s\n", buf);write(fd, str, strlen(str));printf("test2 write mytest.txt finish!\n");close(fd);return 0;
}

两个进程先执行进程1,然后在10秒内执行进程2;执行结果如下:

分析上述结构可知两个进程打开同一文件是可以实现进程间通信的。我们进一步用strace命令追踪进程的系统调用如下图:

用strace命令追踪可知进程1底层的系统调用也是通过调用mmap函数实现的内存映射进行进程间的数据共享,由此我们更加深入的理解mmap函数的运用。

深入理解mmap函数相关推荐

  1. 内存映射mmap函数的理解

    定义: mmap,从函数名就可以看出来这是memory map, 即地址的映射, 是一种内存映射文件的方法. mmap:将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中 ...

  2. 彻底理解mmap()

    彻底理解mmap() 原创 Holy_666 最后发布于2019-01-17 22:51:27 阅读数 5056 收藏 发布于2019-01-17 22:51:27 分类专栏: 服务器 版权声明:本文 ...

  3. mmap()函数参数详解

    author : wfs time : 2019.4.17 功能描述 mmap将一个文件或者其它对象映射进内存.文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清 ...

  4. 深入理解javascript函数系列第二篇——函数参数

    前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数.本文是深入理解javascript函数 ...

  5. C++深入理解虚函数

    c++深入理解虚函数 虚函数的使用方法: (1)在基类用virtual声明成员函数为虚函数.这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便被调用. 在类外定义虚函数时,不必在定义vir ...

  6. 共享内存简介和mmap 函数

    一.共享内存简介 共享内存区是最快的IPC形式,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据. 即每个进程地址空间都有一个共享存储器的映射区,当这块区 ...

  7. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 三 | 等待远程函数执行完毕 | 寄存器获取返回值 )

    文章目录 前言 一.等待远程进程 mmap 函数执行完毕 二.从寄存器中获取进程返回值 三.博客资源 前言 前置博客 : [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | ...

  8. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )

    文章目录 一.准备 mmap 函数的参数 二.mmap 函数远程调用 一.准备 mmap 函数的参数 上一篇博客 [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | 远程调 ...

  9. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 一 | mmap 函数简介 )

    文章目录 一.mmap 简介 二.mmap 函数作用 一.mmap 简介 mmap 函数的作用是 将 文件 映射到 内存中 , 映射的单位必须是 PAGE_SIZE ; mmap 函数引入头文件 : ...

最新文章

  1. 漫谈 Weblogic CVE-2020-2555
  2. 【java】项目环境配置
  3. Python自动化运维——系统进程管理模块
  4. 计算机组成与系统结构名词解释,北京邮电大学 计算机系统结构(体系结构) 期末复习 术语解释...
  5. [精华] VI高级命令集锦
  6. 深度学习之非极大值抑制(Non-maximum suppression,NMS)
  7. php速度慢不怕cpu漏洞,PHP曝远程DOS漏洞可致CPU持续占满,请注意升级_护卫神
  8. nlp-tutorial代码注释3-3,双向RNN简介
  9. 苹果iOS手机暗藏间谍软件的揭秘者:扎徳尔斯基
  10. oracle的表连接-内外连接
  11. 浅谈http协议六种请求方法,get、head、put、delete、post、options区别
  12. 金山安全报告:十大病毒危害排行出炉
  13. TCP的乱序和丢包判断(附Reordering更新算法)-实例case
  14. JAVA基础_数组(一维数组)
  15. 自动驾驶之-MATLAB环境下利用单目摄像头和语义分割创建占位栅格(occupancy grid)
  16. 【Google Play】APK 扩展包 ( 2021年09月 最新处理方案 | 文件准备 | 拷贝文件至内置存储 | 解压及使用扩展文件 )
  17. 华为设备HCNA综合实验配置
  18. git idea创建新分支,获取/合并主支代码的2个方法
  19. H5实现一个简易本地视频播放器
  20. 使用HTML+CSS实现网页loading加载效果,支持定时或加载完成后隐藏

热门文章

  1. 走进MSTP -- 7. 软硬管道
  2. 网上银行转账是怎么测的,设计一下测试用例。
  3. php 项目总结,项目总结
  4. Web容器启动Spring
  5. c语言如何让系统随机生成数,C语言中是如何进行随机数生成的
  6. Stata:多元Logit模型详解(mlogit)
  7. google recaptcha v2 and v3
  8. h5语音聊天audio实战|仿微信语音效果|h5即时聊天系统
  9. 基于Java(SSM框架)实现的购物网站系统【100010082】
  10. 2D激光SLAM-雷达的特征点提取