ZBLOG

mmap

mmap(Memory-mapped Files,内存映射文件)是 Linux/Unix 系统提供的一种将文件直接映射到进程虚拟地址空间的机制。通过 mmap,文件可以像访问内存一样被读写,避免了传统的 read/write 系统调用和用户态缓冲区的拷贝,从而提高 I/O 性能。以下是关键点解析:


1. 核心原理

  • 映射过程
    调用 mmap 后,内核将文件的某一部分(或全部)映射到进程的虚拟地址空间。此时并未实际加载文件数据到物理内存,而是建立虚拟内存到文件的关联。
  • 按需加载
    当进程访问映射区域的某个地址时,触发缺页中断(Page Fault),内核才将对应的文件内容加载到物理内存(惰性加载)。

2. API 函数

#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)。
    • flags:控制映射行为(如 MAP_SHAREDMAP_PRIVATE)。
    • fd:文件描述符。
    • offset:文件偏移量(需按页大小对齐)。

3. 典型应用场景

(1) 高性能文件 I/O

  • 优势:避免用户态与内核态的数据拷贝,适合大文件频繁读写(如数据库、日志处理)。
  • 示例
    
    int fd = open("data.bin", O_RDWR);
    void *ptr = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    // 直接通过 ptr[index] 访问文件内容
    

(2) IPC(进程间通信)

  • 共享匿名映射
    通过 MAP_ANONYMOUS | MAP_SHARED,父子进程共享同一块内存区域。
  • 示例
void *shared_mem = mmap(NULL, size, PROT_READ | PROT_WRITE,
                        MAP_ANONYMOUS | MAP_SHARED, -1,0);
if (fork() ==0){
    //子进程修改 shared_mem
}else{
    //父进程读取 shared_mem
}

(3) Zero-Copy网络传输

  • 结合 sendfile/DMA
    将磁盘文件直接映射到内存,再通过网络接口发送,减少 CPU 参与。

4. mmap vs read/write

特性 mmap read/write
数据拷贝次数 0次(直接操作内存) 2次(内核↔用户缓冲区)
大文件性能 更高(避免频繁系统调用) 较低
小文件开销 可能较高(缺页中断成本) 更轻量
随机访问支持度 天然支持 需 lseek

5.注意事项

  • 对齐要求: offset必须是4096倍数(通常等于系统页大小) -资源释放:使用munmap()解除映射并关闭fd.
munmap(ptr,len); close(fd);

-同步写入:msync()确保修改回写到磁盘.

如果需要深入某个方向(如性能优化陷阱或具体代码案例),可以进一步探讨!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=8324

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?