- 1、本文档共3页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
如何读写磁盘文件
读写磁盘数据是程序设计中最基本也是最重要的操作之一。实际系统为磁盘 I/O 提供了多种接口,不同的接口不但语义有所不同,而且性能也有差异。理解这些接口对实现正确和高效的程序是很重要的,本文将结合内核的实现原理来比较各种磁盘 I/O 系统调用,希望能从最底层来透彻理解这些接口。
内核访问磁盘文件的原理
Linux 内核访问磁盘文件的大体原理如右图所示。
内核数据结构
内核会为每个进程关联一个到 file 结构的指针数组,我们熟悉的文件描述符是这个数组的下标值,数组中每个元素指向一个 file 结构,一个 file 结构代表这个进程打开的一个文件。 file 结构中有一个到 inode 结构的指针(注意,这里的 inode 是一个在内存中结构,而不是保存在磁盘上的 inode),在内核中,每一个 inode 唯一标识一个文件,因此,如果同时有多个进程打开同一个文件,他们的 file 结构指向同一个 inode。 inode 结构中有一个到 page cache 结构的指针,内核为每个文件单独维护一个 page cache,用户进程对文件的大多数读写操作实际上都只是直接作用在 page cache 上面,内核会在适当的时机将 page cache 中的内容写回到磁盘上,这样能够大大减少访问磁盘的次数,从而提高系统性能。
page cache 是 Linux 内核文件访问过程中至关重要的数据结构,我们需要再了解一些关于它的细节。page cache 中保存了用户进程访问过的该文件的内容,这些内容以页为单位保存在内存中,当用户需要访问文件的某个偏移量上的数据时,内核会以偏移量为索引,找到相应的内存页,如果该页还没有读入内存,则需要访问磁盘读取数据。为了提高搜索页的速度同时节省 page cache 数据结构占用的空间,Linux 内核使用基树(radix tree)来保存 page cache 中的页。
访问磁盘数据的系统调用比较
在了解了内核访问磁盘文件的原理之后,我们来比较各种访问磁盘数据的方法。
read/write 系统调用
这是最常用、最基本的文件访问方法,它们的使用方法相信读者已经比较熟悉,就不作介绍了。这对系统调用涉及两个额外的开销:系统调用开销和数据复制开销。
每访问一次文件,都需要产生一次系统调用,但是现在的处理器系统调用的开销通常是比较小的;
数据需要在用户的缓冲区和 page cache 之间进行复制。
mmap 系统调用
mmap 系统调用的原理是将 page cache 中的页直接映射到用户进程的地址空间中去,从而进程可以通过访问自身地址空间中的虚拟地址来访问 page cache 中的页,当然,最后还是需要依靠内核在适当的时候将 page cache 中的内容写回到磁盘。所以,mmap 和 read/write 之间的区别在于
只需映射一次,后续的访问无须系统调用;
数据不需要在用户缓冲区和 page cache 之间复制。
需要特别注意的是,对同一个文件而言,mmap 所访问的和 read/write 访问的是同一个 page cache。
mmap 的原型如下
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
其中 addr 是映射的起始虚拟地址,一般指定为 NULL,这样内核会自动选择合适的地址并作为结果返回给用户。另一个比较重要的参数是 flags,它可以取两个值,分别为 MAP_SHARED 和 MAP_PRIVATE。如果指定为 MAP_SHARED 用户对映射的内存区域的更改会反映在 page cache 上,这样所有读写这个文件的进程相当于共享这片内存区域(read/write 操作也是作用在这个 page cache 上的);如果指定为 MAP_PRIVATE,当用户修改这片内存区域的时候,内核会复制相应的页(Copy On Write),用户的更改只会作用在这些复制出来的页上,而不是作用在 page cache 中,这样其他访问这个文件的进程就不会看到该文件的更改。
使用 mmap 可以提高访问文件的速度,但是这个操作会为内核引入额外的维护开销(需要维护更多的地址空间结构)。通常如果需要访问整个比较大的结构化的二进制文件,使用 mmap 可以提高访问的效率,而且便于编程。
直接读写磁盘设备文件
还有一种不太常用的访问磁盘数据的方法是绕开文件系统,直接读写磁盘设备文件(如 /dev/sda1)。但是从内核的实现来看,这种操作的效率并不比普通的 read/write 系统调用高,因为内核为磁盘
您可能关注的文档
最近下载
- 一种钢铁综合废水浓盐水的减量化、资源化处理组合方法与系统.pdf VIP
- 《碳中和管理体系 要求》(征求意见稿).pdf
- 医院银行存款管理制度.docx VIP
- 新北师大版数学五年级上册第六单元“组合图形面积”单元试卷 .pdf VIP
- 人教版高中英语必修一全册教学课件.pptx
- 《工逆向工程与增材制造》课件——17. Geomagic Design X 草图建模方法 .pptx VIP
- 海姆立克急救法-(精).ppt VIP
- 北师大版九年级下册数学全册同步练习.docx VIP
- 2025全国青少年模拟飞行考核理论知识题库40题及参考答案1套.docx VIP
- 在线网课学习课堂《兵棋(中国人民武装警察部队警官学院)》单元测试考核答案.docx VIP
文档评论(0)