linux下一切皆文件,不管你有没有学过linux,都应该听过这句话,就像java的一切皆对象一样。
今天就来看看它的真面目。
你记住了,只要一个竞争退出它的PCB要被释放文件名,客服表也要被释放。那么,指向这个文件的指针就少了啊,那么可以理解成,如果一个文件只被这一进程打开,这个文件也自动就被关掉了啊。
以前的文章说计算机体系结构的时候,说过最底最底下呢,我们是有一堆的硬件。不知道的可以看一下这个这篇文章花钱买不到系列—linux 冯诺依曼体系结构-CSDN博客
在我们的冯诺伊曼体结构里,这些设备都属于外设。还记得吗啊,属于外设的话,那么不管是键盘显示器磁盘还是网卡外部或外围设备?那么,它任何的数据处理都必须把数据先读到内存,然后处理完毕之后再将内存当中的数据刷新到外设当中。这叫做IO 。
对于我们来讲呢,键盘它也一定要有键盘所对应的一套读写方法。那么,因为我们曾经说过,操作系统为了管理所有的软硬件,那软硬件很多,所以操作系统它就必须得对所有的软硬件资源呢进行先描述,再组织。
所以不管是键盘、显示器、硬盘、网卡,都要有我们对应的结构体,那么它这些结构体里包含了这些设备,每一个设备对应的所有的属性信息。
那么这些设备呢,那么它对应的一定要有自己的对应的IO函数。那么你要输入输出嘛,所以我们也一定要有对应的这些方法,当然除了这些,它肯定还有其他方法啊。今天重点聊这个。
比如说键盘呢,它也一定要有对应的keyboardread()方法。也一定要有int keyboardwrite()方法,那你说我们经常键盘作为输入设备,那它有数据了,我主要是读取它,那么这里呢,读取它我可以理解。那么,其中呢?我什么时候会往键盘去写呢啊?我们从来没有往键盘里写。事实呢,我们也确实不会往键盘去写,但并不妨碍他有个写方法,这个写方法我们可以就是一个null。
那么我们允许你可以那么每一个硬件设备。都要有自己的读写方法,那么你如果天然不支持读或者写,那很好啊,不影响你的方法,为NULL就行了
具体的这些我们硬件的读写方法,一定是在自己的在各种硬件匹配的驱动程序里。
因为不同的硬件,那么它都有自己的读写方法。所以呢,那么每一个文件,它的驱动程序,那么都有自己的读写方法,这个肯定是不一样的。
学了一些这么多概念之后呢,也知道每一种我们对应的硬件,那么它的访问方法啊,方法是一定不一样的。肯定是不一样的,读磁盘怎么能跟读网卡一样呢?读我们的显示器怎么能跟读键盘一样呢?一定是不一样的啊,那么但是你怎么来表示这里的我们的键盘显示器磁盘或者网卡呢?
那么其中我们的linux呢?它做了一个设计,比如说呢,那么只要你进行读写。那么我可以抽象出,比如说键盘读写的时候,我可以认为你的那么目标写入的那个,你的存键盘的存储空间为零。那么你的数据,我在读的时候,那么你也有自己的状态啊,那么包括是被打开的还是被关闭的?那么键盘显示器它的所有的属性呢?我们都可以把它抽象出来啊
所以呢,那么我们linux当中呢,它是这么设计的啊,那么在我们的操作系统内部呢?一切皆文件体现的就是struct file,任何一个被打开的文件在内核里,我们的内核结构的对象就叫做struct feel类型的对象,包括了各种文件的属性啊。虽然底层的这些硬件呢,大家是有差别的读写方法一定不一样,但是属性呢?那么我们是可以通过数据层面上去把它统一下的。
比如说type表示什么类型的文件,status表示打开还是关闭,每一个虽然它打开方式不一样,但你有没有被打开我是知道的啊,所有属性呢?我们其实是可以公共性的抽取出来,只不过大家。属性的个数和具体属性的值写的不一样,但并不影响啊,那么这是其一。
其二呢,将来啊,一切皆文件对于操作系统来讲,操作系统会说啊,不同的文件呢,那么对应的读写方法是不一样的,那么file里面一定充满大量的函数指针。
那么其中呢?当我们打开我们对应的键盘时。把键盘的对应给它创建一个struct filel对象,然后怎么办呢?然后我们把那么read方法数属性初始化之后,让我们的函数指针。指向具体的我们键盘的读方法和键盘的写方法。
多来几个,就变成这个样子
而这个struck file对象里面的所有属性呢?可以根据硬件的不同去填充就可以。我在初始化这里的每一个不同的设备的时候,我们让它的函数指针指向我们,那么具体某一种硬件的读写方法啊,我们给它啊,比如说是我们的显示器的啊,比如说磁盘的读方法,磁盘的写方法,那么网卡的读方法,网卡的写方法。当然中间还有一对软件,只是简单一下,当然每个struct中还有一个指针,指向他们。这就是先描述后组织。
所以站在操作系统,站用户之上,压根不关心你你底层的差异。他要读文件的时候,他压根就不关心你底层。文件的所有的不同,对我看来上层我们无论是操作系统内部要读写这个文件,还是用户。那么,他们看到的只有struct filel读写方法时,他们直接调用对应的函数指针,指向具体方法,但用户不关心。所以在用户级下看到的就是一切皆文件。
所以这是什么?这就是多态,我们只需要使用我们对应的统一文件,那么我们就使用我们就可以访问同样的文件,那么底层的那么差异呢,其实就可以那么体现出来了,这是用C语言来实现的多态的特征啊,那么我们这里的s结构体就相当于是基类。上下下面的所有东西也称为子类,然后呢,这就是一种多态的实现啊。所以为什么现在很多语言都是支持面向对象或者说是多态,这都是经过工程师们的大量软件工程的结果。
到内核里里面看看是不是如我所说struct task_struct {}是进程的pcb
就是这里 struct files_struct,屏蔽底层差异化,在上层看来就是open打开文件close关闭文件
但是转到定义,会发现这里有一个指针数组,是指向被打开的文件
数组的大小是32,默认的
这里有一个二级指针,扩展打开的文件