讲师中心 微信公众号

工具推荐

视频效率加速
Seko
Seko

AI短剧一键生成成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

AniShort
AniShort

AI短剧协同制作平台

c++内存映射文件方法 c++如何使用mmap读写文件

风强小哥_3693

风强小哥_3693

发布时间:2026-03-29 15:43:37

|

406人浏览过

|

来源于php中文网

原创

Linux下mmap文件需三步:open、ftruncate确保文件大小、mmap映射;注意MAP_SHARED回写、msync强持久化、fd须支持映射、错误检查依赖errno。

c++内存映射文件方法 c++如何使用mmap读写文件

Linux 下用 mmap 读写文件,核心就三步:打开 + 映射 + 访问

Windows 没有 mmap,那是 CreateFileMapping 和 MapViewOfFile 的事;C++ 标准库也不提供跨平台内存映射接口。所以谈 mmap,默认你跑在 Linux/Unix 类系统上,且用的是 POSIX 接口。

常见错误是直接对普通文件调用 mmap 却忘了先 ftruncate —— 映射区域不能超出文件当前大小,否则访问时会触发 SIGBUS(不是 SEGFAULT,这点容易误判)。

  • open() 要带 O_RDWR(写必须),如果只读用 O_RDONLY,但后续不能改写
  • ftruncate(fd, size) 必须在 mmap 前调用,确保文件有足够空间——哪怕你只想读,也要保证映射长度 ≤ 文件大小
  • mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0):注意 MAP_SHARED 才能回写到文件;MAP_PRIVATE 改动只在内存,不落盘

mmap 返回 MAP_FAILED 的典型原因

不是所有失败都报 errno = ENOMEM,很多是隐性条件不满足。比如:size 为 0、fd 已关闭、文件系统不支持(如某些 NFS 或 /proc 下的伪文件)、或映射长度超过 RLIMIT_AS 限制。

最容易被忽略的是:文件描述符 fd 必须指向一个**支持 mmap 的文件类型**。普通磁盘文件可以,但管道(pipe)、终端(/dev/tty)、socket、甚至某些 tmpfs 挂载点(取决于内核配置)可能拒绝映射,此时 mmap 直接返回 MAP_FAILED,errno 是 ENODEV 或 EINVAL。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 检查 errno 比检查返回值更关键:用 if (addr == MAP_FAILED) { perror("mmap"); }
  • 映射前用 lseek(fd, 0, SEEK_END) + lseek(fd, 0, SEEK_SET) 确认文件可定位,排除只读挂载或权限问题
  • 不要假设 size 可以任意传——内核要求页对齐,实际会向上按页(通常 4KB)取整,但传入非对齐值本身不报错

写完记得 msync 吗?大多数时候不用,但有些场景必须

MAP_SHARED 下,写内存一般会异步刷盘,类似 write() 后依赖内核回写。如果你需要**强持久化保证**(比如关键日志、数据库 WAL),就得调 msync(addr, size, MS_SYNC) —— 否则断电可能丢数据。

但别滥用:MS_SYNC 是阻塞的,性能开销大;MS_ASYNC 只是“建议内核尽快刷”,不保证顺序或完成时间。多数应用只需依赖内核默认行为,除非你在实现存储引擎或做崩溃一致性校验。

  • msync 前不必 munmap,但 munmap 不触发刷盘
  • 映射区域被 fork() 后,子进程继承映射,但父子写同一地址是否冲突,取决于 MAP_SHARED 还是 MAP_PRIVATE
  • 多线程同时写同一映射区域,需自行加锁——mmap 不提供原子性

C++ 封装 mmap 时,RAII 管理比想象中难

表面看,用 unique_ptr + 自定义 deleter 就能自动 munmap,但漏掉两个关键点:一是 fd 本身也要关,二是 msync 时机不可控。强行塞进析构函数,会导致每次销毁都刷盘,性能崩坏。

更现实的做法是:把映射封装成类,但 msync 暴露为显式方法;fd 和 addr 分开管理生命周期;或者干脆不封装,只在局部作用域里直写三行原生调用——简单逻辑下,少一层抽象反而更稳。

  • 自定义 deleter 里调 munmap 是对的,但别在里面调 close(fd) —— fd 可能被其他地方复用
  • mmap 成功后,addr 是 void*,C++ 中转成具体类型指针要小心对齐和别名规则(比如用 reinterpret_cast 读结构体,确保该结构体无 padding 且按需 packed)
  • 调试时用 /proc/PID/maps 查看映射是否生效、权限位是否正确(rw 还是 r-)
内存映射不是银弹,小文件用 read/write 更轻量,频繁随机访问才显优势;而真正难的从来不是调通 mmap,是怎么在崩溃恢复、并发修改、跨进程同步这些边界上不翻车。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
函子Zion

一款支持AI搭建、可视化编辑和多端发布的全栈无代码开发平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5454

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5611

2025.07.04

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

636

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

391

2025.11.27

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

399

2026.04.23

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3248

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

5469

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3909

2025.12.29

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn