mmap(memory mapping,内存映射)是Linux系统中一种高效的文件访问机制,它通过将文件直接映射到进程的地址空间,使得应用程序可以像访问内存一样访问文件数据。
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等)
- fd
:文件描述符
- offset
:文件偏移量(必须是页面大小的整数倍)
映射建立阶段:
页面访问阶段:
同步与释放阶段:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDWR);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
exit(EXIT_FAILURE);
}
void *addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
// 现在可以通过addr指针访问文件内容
printf("File content: %s\n", (char *)addr);
// 修改文件内容
sprintf((char *)addr, "New content");
// 同步到文件
if (msync(addr, sb.st_size, MS_SYNC) == -1) {
perror("msync");
}
munmap(addr, sb.st_size);
close(fd);
return 0;
}
匿名映射:不关联文件,用于进程间共享内存
void *addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
固定映射:MAP_FIXED指定确切地址(危险操作)
大页支持:通过MAP_HUGETLB使用大页面
非阻塞映射:MAP_POPULATE预先填充页表
mmap是Linux系统中非常强大的内存管理工具,合理使用可以显著提升I/O性能,但也需要开发者充分理解其工作原理和限制。