【Linux】揭开文件神秘的面纱:第二讲,操作系统自己的菜鸟驿站——文件缓冲区

引言

        相信大家在平常网购的时候都使用过菜鸟驿站,当我们网购的快递送到时,快递员会将我们的快递存放在菜鸟驿站中,我们就可以去菜鸟驿站里拿到自己的快递。在这个过程中,菜鸟驿站扮演了一个中转站的角色,我们接下来要讲解的文件缓冲区,与菜鸟驿站有着异曲同工之妙。

文件缓冲区

        在我们先前对文件的学习中,文件缓冲区这个词语经常出现,那么,什么是缓冲区呢?缓冲区是内存空间的一部分,也就是说,内存空间里,有一块存储空间被预留了出来,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。根据其对应的是输入设备还是输出设备还会分为输入缓冲区和输出缓冲区。

用户级缓冲区

        当我们在使用C语言或C++中的函数来输出信息时,无论是printf还是cout或者别的,都不是直接存入文件内核缓冲区中的,而是存在用户级缓冲区中。什么是用户级缓冲区呢?在C语言库里,C语言库会给每一个文件创建一个用户级,语言层的缓冲区,我们输入的信息会先被存到这个缓冲区里面,当出现:缓冲区已满、满足刷新条件、进程退出,这三个条件中任意一个条件满足的时候,由C语言标准库根据文件描述符将缓冲区中的数据刷新到文件内核缓冲区中,交给操作系统。这个过程是不是很像本文最开始举得菜鸟驿站的例子?先保存到一个中转站,然后再交给操作系统。

图片来源网络,如有侵权则删除

        那很多人可能会好奇了,这个用户级缓冲区到底在什么位置呢?之前在讲解文件基础IO的文章中我们曾提过,fopen系列的接口会返回FILE*类型的指针,而FILE是C语言封装的一个结构体,里面不仅有我们之前讲过的文件描述符,我们的用户级文件缓冲区也在里面。

        那为什么要在标准库里设置一个用户级缓冲区呢?为什么不能直接写入系统缓冲区呢?是不是有点多此一举?设置缓冲区的原因是因为系统调用也是有成本的,如果不设置一个用户级缓冲区,每次输出都要进行一次系统调用,成本就会很高并且效率低下。多设置一个用户级的缓冲区,那么我们可以进行多次输出操作,然后通过系统调用将多次输出的数据一次性刷新到系统缓冲区里,效率比一次一次调用高了很多,避免了浪费。反过来呢,当用户需要读取某个文件的数据时,操作系统就可以一次或几次的将用户想要读取的数据全部写入系统缓冲区中,然后进行一次或几次的刷新将数据拷贝给用户级缓冲区,程序就能拿到数据。

刷新条件

        上文我们提到当刷新条件满足时缓冲区就会进行刷新,那么什么时候算满足刷新条件呢?操作系统有以下几种刷新策略:

        1、立即刷新,也叫无缓冲,在系统概念上叫做写透模式,只要输入就立马刷新;

        2、缓冲区满了,全缓冲,缓冲区已满,不刷新就没有位置写了;

        3、行刷新,用户每输入一行就进行一次刷新,以换行符为标志。

        原则上来说,全缓冲的效率是最高的,因为这意味着可以用最少的调用次数完成最多的数据拷贝,一般往普通文件写入时采用这种方式。行刷新,在程序运行时,printf等其他函数内部可能会检测缓冲区最后是否有换行符,如果是就会把包括换行符在内之前所有的内容刷新,一般用于往显示器进行打印。行刷新这种刷新方式设计出来的初衷是比较符合人在日常使用时的习惯。

        需要注意的是,当父进程在缓冲区内写入了数据,但还没有刷新时,如果这时候创建了子进程,子进程会连同父进程的缓冲区也一起复制过去,输出时就会输出两次。

        除了我们上面讲的用户级缓冲区之外,系统缓冲区的刷新机制更加复杂,由操作系统自主决定,在这篇文章中我们不进行讲解,目前我们认为只要将数据交给操作系统就相当于交给了硬件。数据交给操作系统,交给硬件,本质全是拷贝,计算机数据流动的本质就是一切皆拷贝。

理解一切皆文件

        进行一个小拓展。在我们之前的学习中,我们曾提出过一个概念,叫做一切皆文件,可是我们知道,其他的系统级文件还好说,我们的外设,比如键盘,鼠标,磁盘等这种东西,Linux是怎么把它们全部抽象为文件的呢?

        首先,不管是什么硬件,不管是键盘还是鼠标,它们都要给操作系统提供它们的读写接口,虽然它们输入输出的形式不一样,但是都要有这些接口。而在我们的struct file中,存在着两个函数指针,这两个函数指针就对应读接口和写接口,这样一来,就可以直接通过调用外设的读写接口来实现输入和输出。在进程看来,所有硬件我都能以文件的形式访问,这样在上层访问硬件时就不需要在意底层是哪个硬件,调用同名函数就能访问,屏蔽了底层的硬件差异。struct file这一层被称为VFS,即虚拟文件系统。

结语

        这节课带大家学习了有关文件缓冲区的知识,还有理解了一切皆文件到底是怎么实现的,希望大家在看完这篇文章后能从中学到新知识。以后我会继续创作Linux方向的博客,如果觉得有帮助的话希望各位大佬能三联关注支持一下,看到后我会进行回关和回访。

评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值