mmap读大文件变慢主因是默认map_private触发写时复制和缺页中断,应改用只读映射并预取;写回需map_shared+msync;跨进程共享须同文件同标志;windows需注意权限和路径限制。

为什么 mmap 读大文件反而变慢?
不是 mmap 本身慢,而是你没关掉写时复制(COW)或没预取。默认用 PROT_READ + MAP_PRIVATE 映射时,第一次访问页会触发缺页中断+零页映射,对随机访问的大文件(比如几百 MB 的日志),比 read() 更卡。
- 用
mmap.mmap(fd, length, access=mmap.ACCESS_READ)显式指定只读,避免内核悄悄分配写时复制页 - 对顺序扫描场景,加
madvise(MADV_SEQUENTIAL):在mmap后调用os.posix_fadvise(fd, 0, length, os.POSIX_FADV_SEQUENTIAL) - 别在小文件上硬套
mmap——小于 4KB 的文件,系统调用开销反超内存拷贝
mmap 修改文件内容但不落盘?
映射后改内存 ≠ 文件立刻更新,取决于映射标志和同步时机。最常见坑是用了 MAP_PRIVATE 却以为能持久化——它只改副本,原文件纹丝不动。
- 要写回文件,必须用
MAP_SHARED+PROT_WRITE,且确保文件打开时带os.O_RDWR - 改完别忘了
msync():调用mmap_obj.flush()(Python 封装了msync) - 如果只读映射却尝试写,会触发
SIGBUS,Python 抛MemoryError或直接段错误(尤其在 macOS 上)
多进程共享同一块 mmap 怎么不出错?
父子进程能安全共享 MAP_SHARED 映射,但无关进程必须通过命名文件或匿名共享内存(POSIX 共享内存)协作,不能直接传 mmap 对象。
本文档主要讲述的是Delphi语言参考;Delphi是一种结构化、面向对象,类型强健,编译执行的高级语言,其object pascal的语法规范具有易读性好、编译快速、多单元的模块化程序设计等优点。 Delphi技术Borland的组件框架和快速开发环境。大多数情况下,本语法指引假设你使用的是Borland的开发工具。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 跨进程推荐走文件:所有进程打开同一文件,用相同偏移和长度
mmap,且都用MAP_SHARED - 避免用
MAP_ANONYMOUS跨进程——它只在 fork 后有效,无法被其他进程 open 到 - 注意文件锁:即使
mmap是原子的,多个进程同时修改同一区域仍可能覆盖,得配合flock()或fcntl()锁文件区域
Windows 下 mmap 报 PermissionError: [WinError 5] Access is denied
Windows 对内存映射权限更敏感,尤其涉及可执行映射或大内存页时,错误常发生在打开文件方式不对或路径权限不足。
立即学习“Python免费学习笔记(深入)”;
- 确保文件以
os.O_RDWR打开,哪怕只读也要可读可写(Windows 内核要求) - 避免映射到网络路径(SMB)或某些加密卷——Windows
CreateFileMapping默认拒绝 - 若需
PROT_EXEC,得显式加win32event权限或用mmap.ACCESS_COPY替代,否则直接 PermissionError
mmap,而是判断该不该用、用哪种标志、什么时候该 msync、以及 Windows 和 Linux 在 access 参数上的隐式差异。









