先说说体系冯诺依曼的体系结构,有利于我们后面理解操作系统,软件再怎么发展,也必须遵守硬件的规则。
如下图:
很久以前,我们都是把指令打成孔,有孔无孔表示0,1,让计算机读,输出也是对一张纸进行打孔,输出0, 1,为了普及,能让大众使用,而且随着计算机语言的发展,我们需要有一个设备能处理二进制,例如输入一个单词move,然后能转为二进制指令让计算机识别,这也就是我们需要这些输入设备的原因。
同理,当计算机处理完结果,需要反馈结果时,也需要把二进制结果处理为我们能认识的画面和文字,这就是目前的输出设备做的事了。所以说问为什么要有输入输出设备,其实更像问为什么要对二进制做转换,就是为了降低使用难度和工作量呗。
而什么是输入输出设备呢,我认为将数据给内存,给cpu的就是输入设备,cpu将结果返回,最后接收结果就是输出设备。这意味着cpu向磁盘要数据时,磁盘是输入设备,向磁盘输出数据时,磁盘又变成了输出设备,大多设备并非是绝对的输入和输出设备。
体系结构中还有个叫存储器,这个存储器我们可以理解为就是内存,那内存又有什么作用呢,我不能让输入输出设备直接和cpu打交道吗?
假如没有内存, 由于cpu内部的寄存器比较小,能存的数据不多,也就不能预加载数据给cpu,那cpu就只能一点一点向输入设备要数据,而输入设备一般是磁盘文件,读取数据比较慢,不能快速传数据给cpu,cpu的处理速度太快了,一下子把给的数据处理完了,后面的数据又还没来,那cpu就只能等了,那此时cpu就被拖累了。 而且当cpu要输出结果时,写入磁盘文件同样很慢,假如此时cpu内存了不少结果要返回,但是由于写入太慢了,此时cpu又只能等你把结果都写入了,我才能继续计算,此时计算机的效率就由输入输出设备存储速度决定,再好的cpu都提高不了效率,所以结构得改,怎么快速地多存点数据给cpu呢?可以多弄几个寄存器,这样访问速度不就很快了,但是价格太贵,所以不能弄太多寄存器,那我们就选择弄一个便宜一点,存储速度勉强跟得上cpu的"寄存器"。如下
可是不对啊,你数据先从输入设备到存储器,然后才给cpu, 输出数据也是要先给内存,再给输出设备,这不是比我输入设备直接给cpu,cpu结果直接给输出设备慢吗(只有输入输出设备和cpu的结构下文我们称为结构2)
这里有个误区, 那就是并行和串行的关系,冯诺依曼体系结构中数据的流动是并行的,你以为cpu是傻傻地等数据从输入设备到内存,再给自己,实际上数据会预加载到内存,预加载的时候cpu可以去做其它的计算,这样CPU就不用等待你输入数据,可以解放出来,然后内存的读取速度比外设快,所以当cpu要数据时,也可以快速提供,结果也是快速地写给内存,然后让内存去慢慢地给输出设备,不就又把cpu从输出中解放了吗,整体效率呈现的是内存的存储速度。而结构2没有内存这个存储器,就不能预加载,只能来一点数据,此时数据流动就是串行的,整体效率呈现的是外设的存储速度。
综上内存的作用1:此时读数据的时候cpu就被解放去做其它事情了。作用2:内存可以快速传给cpu,作用3:内存的出现降低了电脑的成本,使得计算机可以更普及,因为还有一种结构是增加很多的寄存器给cpu,也能让cpu从io中解放。
好好好,你说内存这么有用那我就听你的喽,可是我还有个疑惑,是谁让内存预加载,是谁在指挥那些硬件干活呢?下面的cpu会提及。
运算器理解很简单,就是对数据,指令做运算,而控制器我理解则是cpu要去控制其它硬件,比如cpu执行了一条代码scanf,要我们输入数据,这个时候cpu就要控制外设,赶紧接收数据给我,我等着运算呢,我也是基于这一点大致理解虽然外设和cpu没有数据的传输,却有控制信号直接连接,或许后面的到linux网络部分会理解地更深刻。
到了这里我们就大致理解了五大硬件的作用,可是好像少了什么东西,对,软件呢,软件在哪里和硬件交互呢,软件的本质就是一句一句的指令,指令最后那就是数据,由计算机体系结构要求,要让cpu处理软件的指令,那就要让软件加载到内存,所以软件就在内存。还有就是先前让内存预加载的指令就是操作系统这个软件给cpu发的指令,让控制器去实施的。那为什么是操作系统发指令呢,我代码写了一句scanf,不是我的编译器对cpu发号施令吗?下面来看看操作系统,我们就知道了。
我们总说cpu处理指令,处理数据,数据去内存拿,指令呢,谁传到内存,然后传给cpu的,谁呢?这就是我们的操作系统了,噢,那我就理解了为什么说操作系统控制硬件了,就是将指令发给cpu,让硬件干活,先前说操作系统是这个软件要加载到内存,才能让cpu访问执行,所以操作系统就在内存,而由内存断电就丢失数据得,电脑每次开机,连接电源时都要先把操作系统加载到内存。
那为什么是让操作系统去给硬件发指令呢,我的QQ,微信,编译器软件就不能发吗,不行,因为操作系统不信任这些软件,如果让这些软件随意访问硬件资源,那你的设备数据将随意地由其它软件获取。那QQ微信难道不需要硬件的支持吗,这个当然是需要的,接下来就谈谈计算机的层状结构来理解QQ微信是如何获得硬件支持的。
如下图
先前说操作系统控制硬件,可是我们可以看到硬件和操作系统中间还有个驱动程序,我理解的驱动程序是什么呢,就是从硬件拿数据给操作系统的,因为操作系统要对进程,文件,驱动做管理,那就都要访问硬件拿数据,所以将从硬件拿数据的功能独立出来,让大家共用(驱动程序也不能理解为函数,网上资料也看不太懂,我才刚接触操作系统,具体理解为什么,也不好说,希望以后工作中慢慢体会)。虽然操作系统对硬件做了封装,但是仅仅保护硬件资源不是操作系统的价值,就像一家银行金库封的死死地,却不为你提供服务,你说这银行硬件条件再好有什么用呢? 所以必须在保证安全的前提下,提供一个小窗口能让用户取钱存钱,所以操作系统也必须将一些接口给外部,而这个接口就是一个一个的函数,基于这个接口不同的语言对系统调用进行封装,c语言printf调用向显示器打印数据的接口,而c++的cout也是调用类似的接口,所以语言的库的都是在系统调用接口之上开发的。从硬件到系统软件,再到封装的系统调用接口的库函数,再到我们使用的软件,不断地封装,包含个头文件,写个printf就能打印数据,我们轻轻一点就能发送消息,实际上却是底层在一层一层地响应。
我很久以前看到个问题,操作系统是c语言写的,语言的开发又是在系统之上,那c语言都还没开发出来咋写的操作系统呢?我现在大致能解释了,语言的开发应该说的就是实现一个个便利的库函数,scanf这些库函数是对系统调用接口进行封装,当然得在系统之上,而没有这些库函数,c语言也能写代码,难道没有成语,就写不了文章了?
好好好,计算机的层状结构我大致理解了,也就明白操作系统对上是要提供接口和服务的,对下是要做软硬件资源管理的,那咋管的呢?
操作系统是怎么知道什么时候给指令给cpu,给什么指令呢?要解释这个得先说说什么是管理,比如在大学里,大学校长就是管理学校的,管理成千上万的师生,可是我们几乎没见过校长,我是怎么被管的呢?这难道说明管理者与被管理者无需见面,也能实现管理,实际上校长只需要获取你的学习成绩,就能判断你成绩合不合格,要不要让你继续读下去,这就已经在管理你了(这点非常关键),噢,那管理者与被管理者见面也是为了获取状态数据,所以只要管理者能从其它方面获取到数据,也就不用和你见面也能通过数据知道你的情况,而且这个数据足够详细,就能描述你,组合在一起能让管理者做出决策。
好好好,那数据哪来,校长去搜集吗,校长是做决策的,校长应该让辅导员来返回你的数据给他,也就是说操作系统不会自己去搜集数据?,而是让一个一个的程序去返回数据给自己,而这些程序就叫驱动程序,可是辅导员哪知道要采集哪些数据呢,总不能把学生的,他们父母的所有数据都一股脑地全传给校长吧,此时校长如果只想找身高最高的同学,那读取数据对校长来说就得累死,数据量太大了,有些可能是没必要的数据,如何对这些庞杂的数据做管理呢?
校长说我给你们一个模板,你们就按照这个模板填数据,除模板需要的其它都不用填,这就减少了数据的采集,但是由于表格比较容易受损,所以校长打算放到网络上去维护,一个学生的信息是各种类型的数据,而操作系统是c语言写的?,所以只能用一个结构体将这些数据统一封装,也就是说一个结构体也就可以描述一个学生,那所有学生都被存在了一个个结构体中。而这个模板就是先对学生进行描述的过程,这一步非常关键,数据的准确度和详细程度大大影响校长的判断。
那我们如何管理这些结构体对象,这不就是数据结构吗,可以用链表将一个一个的结构体组织起来,这个时候校长对学生信息表格的维护就变成对链表的增删查改,那只要再实现配套函数例如find,erase,那每次就调用配套管理函数就能实现管理了。最终这还引出了一个通用的思想,管理就是先描述,再组织。而操作系统要管理文件,内存和进程,那也是先描述,再组织,所以在操作系统内就是存在大量的数据结构。
实际上我们实现的类都是先描述,再组织,例如实现的容器vector,内部是连续存储的,而我们只需要三个指针就能描述vector,其内部的每个元素则由动态开辟的连续空间联系起来,随后就是对这个空间内元素的增删改查,而c++提供容器则是为了帮我们更好地组织对象,例如想让数据以链表的方式组织起来,那就用list,想排序就用map。
由于后面的博客要开始提及进程,那我们就浅谈一下操作系统如何对进程进行管理,由上述情况得,对进程,那不就是先描述,再组织呗,进程就是一个加载到内存的程序,所以进程包括代码和数据,而操作系统管理进程不用在意它的代码和数据,只要用一个描述进程的结构体(linux下称为-PCB)就可以达到管理的目的。