进程使用 posix_fadvise()函数,可就进程对特定文件可能采取的数据访问模式向内核提出
建议。内核可籍此来优化对缓冲区高速缓存的应用,进而提高 I/O 性能
posix_fadvise()系统调用运行进程就自身访问文件数据时可能采取的模式通知内核。
#include <fcntl.h>
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
内核可以(但不是非要)根据posix_fadvise所提供的信息来优化对缓冲区高速缓存的使用,进而提高进程和整个系统的性能。调用posix_fadvise对程序语意无影响。
参数fd是文件描述符,调用期望通知内核进程对fd指代文件的访问模式
参数offset和len确定了建议所适用的文件区域:
- offset 指定了区域起始的偏移量
- len 指定了区域的大小(以字节数为单位)。len 为 0 表示从 offset 开始,直至文件结尾。(在内核 2.6.6 版本之前,len 为 0 就表示长度为 0 个字节。
参数advice表示进程期望对文件采取的访问模式,具体为以下参数之一:
- POSIX_FADV_NORMAL(默认值):进程对访问模式无建议。在Linux中,该操作将文件预读窗口大小设置为默认值(128K)
- POSIX_FADV_SEQUENTIAL:进程预计会从低偏移量到高偏移量读取数据。在Linux中,该操作将文件预读窗口大小设置为默认值的两倍
- POSIX_FADV_RANDOM:进程预计以随即顺序访问数据。在Linux中,该选项会禁用文件预读
- POSIX_FADV_WILLNEED:进程预计会在不久的将来访问指定的文件区域。
- 内核将由offset和len指定区域的文件数据预先填充到缓冲区高速缓存中。后继对该文件的read()操作将不会阻塞磁盘IO,只需要从缓冲区高速缓存中抓取数据即可。
- 对于从文件读取的数据在缓冲区高速缓存中能保留多长时间,内核并无保证
- 如果其他进程或内核的活动对内存存在强劲需求,那么最终会重用到这些页面。换言之,如果内存压力高,程序员就应该确保 posix_fadvise()调用和后续 read()调用间的总运行时长较短。(Linux 特有的系统调用 readahead()提供了与 POSIX_FADV_WILLNEED 操作等效的功能。)
- POSIX_FADV_DONTNEED:进程预计在不久的将来将不会访问指定的文件区域。
- 这一操作给内核的建议是释放相关的高速缓存页面(如果存在的话)
- POSIX_FADV_NOREUS:进程预计会一次性地访问指定文件区域,不再复用。
- 这等于提示内核对指定区域访问一次后即可释放页面。、
- 在 Linux 中,该操作目前不起作用。
对 posix_fadvise()的规范是 SUSv3 中的新增内容,并非所有 UNIX 实现都支持该接口。Linux 内核从 2.6 版本开始提供 posix_fadvise()。