面试题答案
一键面试mmap()函数基本原理
mmap() 函数用于创建一个内存映射区,将一个文件或者其它对象映射到进程的地址空间。它使得进程可以像访问内存一样访问文件内容,内核会将文件内容的部分或者全部加载到内存映射区,这种映射关系建立后,对映射区的操作会直接反映到文件上,反之亦然。当进程访问映射区而对应内容不在内存时,内核会触发缺页中断,从文件中加载相应数据到内存。
函数原型
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
主要参数作用
- addr:指定映射区的起始地址,通常设为
NULL
,表示由系统自动选择合适的地址。 - length:映射区的长度,以字节为单位。
- prot:映射区的保护权限,常用取值有:
PROT_READ
:映射区可读。PROT_WRITE
:映射区可写。PROT_EXEC
:映射区可执行。PROT_NONE
:映射区不可访问。
- flags:影响映射的各种标志,常用取值有:
MAP_SHARED
:共享映射,对映射区的修改会反映到文件中,并且其他映射该文件的进程也能看到这些修改。MAP_PRIVATE
:私有映射,对映射区的修改不会反映到文件中,而是产生一个写时复制(copy - on - write)的副本。
- fd:要映射的文件描述符,由
open()
函数打开文件获得。 - offset:文件偏移量,指定从文件的何处开始映射,必须是系统页大小的整数倍。
mmap()相较于传统文件I/O(fread/fwrite)的优势
- 减少数据拷贝次数:传统文件I/O通常需要先将数据从内核缓冲区拷贝到用户空间缓冲区(
fread
),然后再从用户空间缓冲区拷贝到应用程序的目标位置;写操作则相反。而mmap()通过内存映射,直接在用户空间和文件之间建立映射,减少了内核空间到用户空间的数据拷贝,提高了数据传输效率。 - 提高I/O性能:对于大文件的读写,mmap() 避免了频繁的系统调用开销,因为对映射区的操作就像对内存操作一样,不需要每次读写都调用
fread/fwrite
等系统函数,减少了上下文切换的开销,从而提升整体I/O性能。 - 支持高效的随机访问:使用mmap() 后,程序可以像访问内存数组一样对文件进行随机访问,无需像传统I/O那样进行繁琐的文件定位(
fseek
)和读写操作,提高了对文件中任意位置数据访问的效率。