mmap详解
想写一篇文章,详细的介绍一下mmap,主要是原理、用法、mmap泄露来进行介绍。说到mmap,首先得从堆空间说起。
申请堆空间
其实,不管是 32 位系统还是 64 位系统,内核都会维护一个变量 brk,指向堆的顶部,所以,brk 的位置实际上就决定了堆的大小。Linux 系统为我们提供了两个重要的系统调用来修改堆的大小,分别是 sbrk 和 mmap。接下来,我们来学习这两个系统调用是如何使用的。我们先来看 sbrk。
sbrk
sbrk 函数的头文件和原型定义如下:
#include <unistd.h>void* sbrk(intptr_t incr);
sbrk 通过给内核的 brk 变量增加 incr,来改变堆的大小,incr 可以为负数。当 incr 为正数时,堆增大,当 incr 为负数时,堆减小。如果 sbrk 函数执行成功,那返回值就是 brk的旧值;如果失败,就会返回 -1,同时会把 errno 设置为 ENOMEM。
在实际应用中,我们很少直接使用 sbrk 来申请堆内存,而是使用 C 语言提供的 malloc 函数进行堆内存的分配,然后用 free 进行内存释放。这里你要注意的是,malloc 和 free 函数不是系统调用,而是 C 语言的运行时库。Linux 上的主流运行时库是 glibc,其他影响力比较大的运行时库还有 musl 等。C 语言的运行时库多是以动态链接库的方式实现的。
在 C 语言的运行时库里,malloc 向程序提供分配一小块内存的功能,当运行时库的内存分配完之后,它会使用 sbrk 方法向操作系统再申请一块大的内存。我们可以将 C 语言的运行时库类比为零售商,它从操作系统那里批发一块比较大的内存,然后再通过零售的方式一点点地提供给程序员使用。
mmap
另一个可以申请堆内存的系统调用是 mmap,它是最重要的内存管理接口。mmap 的头文件和原型如下所示:
#include <unistd.h>
#include <sys/mman.h>void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);
我来解释一下上述代码中的各个变量的意义:
start 代表该区域的起始地址;
length 代表该区域长度;
prot 描述了这块新的内存区域的访问权限;
flags 描述了该区域的类型;
fd 代表文件描述符;
offset 代表文件内的偏移值。
mmap 的功能非常强大,根据参数的不同,它可以用于创建共享内存,也可以创建文件映射区域用于提升 IO 效率,还可以用来申请堆内存。决定它的功能的,主要是 prot, flags和 fd 这三个参数,我们分别来看看。
prot 的值可以是以下四个常量的组合:
PROT_EXEC,表示这块内存区域有可执行权限,意味着这部分内存可以看成是代码段,它里面存储的往往是 CPU 可以执行的机器码。
PROT_READ,表示这块内存区域可读。
PROT_WRITE,表示这块内存区域可写。
PROT_NONE,表示这块内存区域的页面不能被访问。
而 flags 的值可取的常量比较多,你可以通过 man mmap 查看,这里我只列举一下最重要的四种可取值常量:
MAP_SHARED:创建一个共享映射的区域,多个进程可以通过共享映射的方式,来共享同一个文件。这样一来,一个进程对该文件的修改,其他进程也可以观察到,这就实现了数据的通讯。
MAP_PRIVATE:创建一个私有的映射区域,多个进程可以使用私有映射的方式,来映射同一个文件。但是,当一个进程对文件进行修改时,操作系统就会为它创建一个独立的副本,这样它对文件的修改,其他进程就看不到了,从而达到映射区域私有的目的。
MAP_ANONYMOUS:创建一个匿名映射,也就是没有关联文件。使用这个选项时,fd 参数必须为空。
MAP_FIXED:一般来说,addr 参数只是建议操作系统尽量以 addr 为起始地址进行内存映射,但如果操作系统判断 addr 作为起始地址不能满足长度或者权限要求时,就会另外再找其他适合的区域进行映射。如果 flags 的值取是 MAP_FIXED 的话,就不再把addr 看成是建议了,而是将其视为强制要求。如果不能成功映射,就会返回空指针。
通常,我们使用私有匿名映射来进行堆内存的分配。
我们再来看参数 fd。当参数 fd 不为 0 时,mmap 映射的内存区域将会和文件关联,如果fd 为 0,就没有对应的相关文件,此时就是匿名映射,flags 的取值必须为MAP_ANONYMOUS。
明白了 mmap 及其各参数的含义后,你肯定想知道什么场景下才会使用 mmap,我们又该怎么使用它。
mmap 的其他应用场景
mmap 这个系统调用的能力非常强大,我们在后面还会经常遇到它。在这节课里,我们先来了解一下它最常见的用法。
根据映射的类型,mmap 有四种最常用的组合:
其中,私有匿名映射常用于分配内存,也就是我们上文讲的申请堆内存,而私有文件映射常用于加载动态库。
这里我们重点看看共享匿名映射。我们通过一个例子,来了解一下 mmap 是如何用于父子进程之间的通信的,它的用法示例代码如下:
共享匿名映射 / 匿名共享映射
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc,char* argv[])
{pid_t pid;char* shm = (char*)mmap(0, 4096, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0);if(!(pid = fork())){sleep(1);printf("child got a message: %s\n",shm);sprintf(shm, "%s", "hello, father.");exit(0);}sprintf(shm, "%s", "hello, my child");sleep(2);printf("parent got a message: %s\n", shm);return 0;
}
wj@wj:~/WORK/Learning/learning/cpp_learning$ gcc test.c -o test.out
wj@wj:~/WORK/Learning/learning/cpp_learning$ ./test.out
child got a message: hello, my child
parent got a message: hello, father.
在这个过程中,我们先是用 mmap 方法创建了一块共享内存区域,命名为 shm,接着,又通过 fork 这个系统调用创建了子进程:具体来讲,子进程休眠一秒后,从 shm 中取出一行字符并打印出来,然后又向共享内存中写入了一行消息。
在子进程的执行逻辑之后,是父进程的执行逻辑:父进程先写入一行消息,然后休眠两秒,等待子进程完成读取消息和发消息的过程并退出后,父进程再从共享内存中取出子进程发过来的消息。
我想请你结合我刚才的讲解,来分析一下这个程序运行的结果,这样你就理解的更透彻
了。
关于共享匿名映射,我们就讲到这里,至于 mmap 的另一个组合共享文件映射。它的作用其实和共享匿名映射相似,也可以用于进程间通讯。不同的是,共享文件映射是通过文件名来创建共享内存区域的,这就让没有父子关系的进程,也可以通过相同的文件创建共享内存区域,从而可以使用共享内存进行进程间通讯。
私有匿名映射
mmap用途小结
mmap最常见的四种用途分别是:
- 私有匿名映射,用于分配堆空间;
- 私有文件映射,用于加载动态链接库;
- 共享匿名映射,用于父子进程之间通讯;
- 共享文件映射,用于多进程之间通讯。
mmap原理
私有匿名映射
私有文件映射
共享文件映射
共享匿名映射
相关文章:

mmap详解
想写一篇文章,详细的介绍一下mmap,主要是原理、用法、mmap泄露来进行介绍。说到mmap,首先得从堆空间说起。 申请堆空间 其实,不管是 32 位系统还是 64 位系统,内核都会维护一个变量 brk,指向堆的顶部&…...

项目02—基于keepalived+mysqlrouter+gtid半同步复制的MySQL集群
文章目录 一.项目介绍1.拓扑图2.详细介绍 二.前期准备1.项目环境2.IP划分 三. 项目步骤1.ansible部署软件环境1.1 安装ansible环境1.2 建立免密通道1.3 ansible批量部署软件1.4 统一5台mysql服务器的数据 2.配置基于GTID的半同步主从复制2.1 在master上安装配置半同步的插件,再…...

【EI征稿】第二届机械电子工程与人工智能国际学术会议(MEAI 2023)
第二届机械电子工程与人工智能国际学术会议(MEAI 2023) The 2nd International Conference on Mechatronic Engineering and Artificial Intelligence 2023年第二届机械电子工程与人工智能国际学术会议(MEAI 2023)计划将于2023年…...
ros2 学习launch文件组织工程 yaml配置文件
简单范例 功能描述 使用launch文件,统一管理工程,实现img转点云,发送到img_pt的topic,然后用reg_pcl节点进行subscribe,进行点云配准处理,输出融合后的点云到map_pt的topic。最后由rviz2进行点云展示。 …...

奇舞周刊第 505 期:实践指南-前端性能提升 270%!
记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ 实践指南-前端性能提升 270% 当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多…...

【C++】泛型编程 | 函数模板 | 类模板
一、泛型编程 泛型编程是啥? 编写一种一般化的、可通用的算法出来,是代码复用的一种手段。 类似写一个模板出来,不同的情况,我们都可以往这个模板上去套。 举个例子: void Swap(int& a, int& b) {int tmp …...

web前端——简单的网页布局案列
✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(简单好用又好看) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 目录 问题背景 解决样例 …...

线程安全问题(3)--- wait(),notify()
前言 在多线程的环境下,我们常常要协调多个线程之间的执行顺序,而为了实现这一点,Java提供了一些方法来帮助我们完成这一点。 一,wait() 作用: 使当前线程进入等待状态 释放当前的锁 (即该方法必须和 synchrnized 关键…...
【Android知识笔记】进程通信(一)
一、Android Framework 用到了哪些 IPC 方式 Linux 的 IPC 方式有: 管道Socket共享内存信号信号量消息队列管道通信 管道是基于pipefs文件系统实现的,也就是多个进程通过对同一个文件进行读写来实现进程间通信。半双工,单向的,通过 pipe(fds) 系统函数调用可得到一对文件描…...

存储空间压缩6倍 ,多点DMALL零售SaaS场景降本实践
🧑💼 作者简介 冯光普:多点 DMALL 数据库团队负责人,负责数据库稳定性建设与 DB PaaS 平台建设,在多活数据库架构、数据同步方案等方面拥有丰富经验。 杨家鑫:多点高级 DBA,擅长故障分析与性能…...

BGP路由属性
任何一条BGP路由都拥有多个路径属性(Path Attributes),当路由器通告BGP路由给它的对等体时,该路由将会携带多个路径属性,这些属性描述了BGP路由的各项特征,同时在某些场景下也会影响BGP路由优选的决策。 一…...

Java面试常用函数
1. charAt() 方法用于返回字符串指定索引处的字符。索引范围为从 0 到 length() - 1。 map.getOrDefault(num, 0) :如果map存在num这个key,则返回num对应的value,否则返回0. Arrays.sort(nums); 数组排序 Arrays.asList("a","b",&q…...

linux编译curl库(支持https)
openssl下载和编译 https://www.openssl.org/source/old/ 解压 tar -xvf openssl-3.0.1.tar.gz cd openssl-3.0.1/配置 ./config如果是编译静态库加入 -fPIC no-shared 如果指定安装路径,使用 --prefix=/usr/local/openssl/选项指定特定目录 编译和安装 make sodu make i…...
Ei Scopus检索 | 2024年第三届能源与环境工程国际会议(CFEEE 2024)
会议简介 Brief Introduction 2024年第三届能源与环境工程国际会议(CFEEE 2024) 会议时间:2024年9月1日-3日 召开地点:新西兰奥克兰 大会官网:https://www.cfeee.org/ 2024年第三届能源与环境工程国际会议(CFEEE 2024) 将于2024年12月12日至1…...
thinkphp6(tp6)创建定时任务
使用 thinkphp6 框架中提供的命令行形式实现定时任务 一、创建一个自定义命令类文件 php think make:command Hello 会生成一个 app\command\Hello.php 命令行指令类,我们修改内容如下: <?php declare (strict_types1);namespace app\command;use …...

【学习笔记】C++ 中 static 关键字的作用
目录 前言static 作用在变量上static 作用在全局变量上static 作用在局部变量上static 作用在成员变量上 static 作用在函数上static 作用在函数上static 作用在成员函数上 前言 在 C/C 中,关键字 static 在不同的应用场景下,有不同的作用,这…...

攻防世界-web-file_include
1. 题目描述 打开界面,如下代码: 代码很简单,从参数中获取到filename然后include这个filename 2. 思路分析 2.1 首先参考常见做法,将参数设置为php://filter/readconvert.base64-encode/resourceflag.php,看是否有…...
C语言的函数指针、指针函数, 函数数组
函数指针 是指向函数的指针,它允许您在程序运行时动态选择要调用的函数。函数指针可以像普通变量一样传递、存储和使用,这使得它们在许多编程场景中非常有用,如回调函数、函数表、插件架构等。 以下是一个简单的例子来说明函数指针的概念&a…...

笔记本开启WiFi
笔记本开启WiFi 为了节省流量:笔记本开启WiFi 条件 支持热点的电脑;我的是华硕飞行堡垒7。 注意事项 笔记本连接公司网络,公司网络通常都在监管下的,手机连接wifi后,刷抖音、购物网站,公司后台会捕获你…...
力扣第37天----第322题、第279题
力扣第37天----第322题、第279题 文章目录 力扣第37天----第322题、第279题一、第322题--零钱兑换二、第279题--组合总和 Ⅳ 一、第322题–零钱兑换 整体思路,跟前面的几道完全背包差不多,就不具体解释了。有一些细节要注意,见代码注释。…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...