linux系统编程——文件IO——给内核提供建议
1. 什么是提供建议
通过 madvise() ,进程可以给内核提供建议,以提高文件IO性能。
2. 对映射用法提供建议
int madvise(void *addr, size_t len , int advice);
@len : 若为0,则建议会应用到addr开始的整个映射。
@advice:描述该建议:
POSIX只规定了建议是什么意思,没规定建议的结果,2.6版本内核如下
MADV_NORMAL : 无建议,按照一般方式处理
内核的行为不变,执行适当数量的预读操作
MADV_RANDOM : 以随机(非顺序)方式访问指定页面
内核禁用预读,每次实际读取操作时会进行最少量的读数据
MADV_SEQUENTIAL : 以顺序方式(从低地址到高地址)访问页面
内核会积极进行预读
MADV_WILLNEED : 在不久的将来,程序将访问页面
内核会发起预读,开始将指定页面读取到内存
MADV_DONTNEED : 不久的将来,程序不打算访问页面
内核会释放特定页面相关任何资源,并丢弃任何被修改且未同步的页面,随后对映射数据的访问将导致数据的页面从支持文件被读进来。
典型用法:
以顺序方式访问内存区域[addr, addr+len]
ret = madvise(addr, len, MADV_SEQUENTIAL);
3. 对一般文件IO用法提供建议
3.1 posix_fadvise()
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
将[offset, offset + len] 范围内的建议提供给内核。若len为0,则将应用到[offset, length of file]范围的内存。
典型用法是将 offset len 都指定为0,则建议会应用到整个文件。
@advice
POSIX_FADV_NORMAL:一般处理
内核正常预读
POSIX_FADV_RANDOM:随机读
内核禁用预读,每次只读取最少量数据
POSIX_FADV_SEQUENTIAL:顺序读
内核积极使用预读,将预读窗口加大
POSIX_FADV_WILLNEED:不久将来,将访问所指定范围
内核发起预读
POSIX_FADV_NOREUSE:不久将来,将访问所指定范围,但只访问一次
同POSIX_FADV_WILLNEED,新的内核可能进行优化
POSIX_FADV_DONTNEED:不久的将来,程序不打算访问页面
内核在指定的范围中从页缓存收回被缓存的任何数据。
int ret = posix_fadvice(fd, 0, 0, POSIX_FADV_RANDOM);
3.2 readahead
readahead 是 linux特有的,行为和 posix_fadvise 的 POSIX_FADV_WILLNEED 一致
4. 建议是廉价的
由于磁盘相对于cpud太慢了,所以小小的建议可以提供莫大的好处。
如,读文件前,进程可以提供 POSIX_FADV_WILLNEED,让内核进行预读,IO将在后台进行,当程序访问文件时,IO操作能顺序完成。
当读取或写入许多数据后,进程可以提供 POSIX_FADV_DONTNEED,让内核从页面回收特定数据块,一个流媒体程序会不断填充页缓存,
所以若程序不打算再次访问这些数据,最好定期将数据回收。
读整个文件的进程可以提供 POSIX_FADV_SEQUENTIAL,让内存积极预读。
而随机读文件,以查找数据,则提供 POSIX_FADV_RANDOM.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?