【Linux】mmap文件内存映射
📝前言:
这篇文章我们来讲讲Linux——mmap
mmap
介绍mmap
接口介绍mmap
使用示例
🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏
这里写目录标题
- 一,mmap介绍
- 1. 基本介绍
- 2. mmap的优势
- 二,接口介绍
- 1. mmap建立映射
- 2. munmap取消映射
- 三,使用示例
- 1. 写入映射
- 2. 读取映射
- 3. 简单模拟实现malloc
一,mmap介绍
1. 基本介绍
- 允许用户空间程序将文件或设备的内容直接映射到进程的虚拟地址空间中。(直接建立虚拟内存到文件页缓存的映射关系)
2. mmap的优势
通过 系统调用mmap
,程序可以高效地访问文件数据,而无需通过传统的 read
或 write
系统调用进行数据的复制
具体来说:
-
传统的
read
和write
分为两步(下面以write
为例)- 第一步:用户态空间缓冲区 → 内核页缓冲区(其实就是内核文件缓冲区)
- 第二步:内核页缓冲区 → 磁盘
-
使用
mmap
- 映射阶段:内核将文件映射到进程的虚拟地址空间,但物理内存尚未分配(讲页表的时候提到的:延迟申请,当真正访问阶段需要的时候才缺页中断分配)
- 修改数据:进程直接修改映射的内存(相当于直接修改内核的页缓存),无需调用
write
,也无用户态到内核态的数据拷贝
注意:当内核页缓存修改好了,我们就认为改好了,我们不关心内核缓冲区到磁盘的刷新这一过程(复杂)
二,接口介绍
当我们建立好映射以后,就可以直接对“开辟”的空间进行操作(虚拟地址)
我们对虚拟地址的操作,都是直接修改映射的内存。
1. mmap建立映射
头文件:
函数原型
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
参数说明
addr
:建议的映射起始地址(通常设为NULL
,由内核自动选择)length
:映射区域的长度(必须是页大小(4 KB)的整数倍,如4096
字节)prot
:映射区的内存保护模式选项(用|
链接)PROT_READ
:映射区可读PROT_WRITE
:映射区可写PROT_EXEC
:映射区可执行- 注意:映射权限必须
<=
文件打开权限
flags
:映射类型(如MAP_SHARED
或MAP_PRIVATE
)MAP_PRIVATE
:创建⼀个私有映射。对映射区域的修改不会反映到底层文件中。(即:修改仅对当前进程有效(写时复制,类似fork
)MAP_SHARED
:创建⼀个共享映射。对映射区域的修改会反映到底层文件中(即:修改会同步到文件,其他进程可见)MAP_ANONYMOUS
:指定要创建⼀个匿名内存映射
fd
:文件描述符(匿名映射时设为-1
)offset
文件偏移量(开始映射的位置相较于0位置处的偏移)(必须是页大小的整数倍)
返回值
- 成功:返回映射区的起始地址(虚拟地址)
- 失败:返回
(void*) -1
或者MAP_FAILED
(等效的)
注意
- 映射的要是一个已经打开的文件!
- 文件大小为
0
的文件无法映射,需要先调整文件大小ftruncate(fd, SIZE)
(会把文件的内容全部初始化成