冯·诺依曼结构
我们常见的计算机,比如笔记本,台式电脑。以及一下不常见的计算机,比如服务器,几乎都遵循冯诺依曼体系结构。冯诺依曼体系结构可以说是计算机的灵魂,如果没有这个结构的提出,计算机就不可能走向百姓,以低成本完成高速的运算。接下来,我就为大家讲解这个结构的设计理念。
常见的冯诺依曼体系结构图如下:
我们认识的计算机,都是由一个个硬件组成的,按照以上图片,我们可以分为以下区域:
- 输入设备:包括键盘,鼠标等
- 输出设备:显示器,打印机,网卡,显卡等
- 中央处理器CPU:计算机完成运算的核心部件,包括
运算器
与控制器
- 存储器
对于存储器,我这里要特地说明:
存储器就是内存
虽然计算机绝大部分数据存储在硬盘中,但是硬盘不是存储器,硬盘是输入输出设备,比如从硬盘读取数据,以及把数据写入硬盘
如果我们只考虑数据的流动,我们可以得到以下逻辑关系:
以上关系中,我们可以提炼出两点:
- 所有外设,即输入输出设备,都只能和内存交换数据
- CPU只能和内存交换数据
可见,内存在计算机中起到了核心枢纽的作用,那么为什么要这么做呢?为什么不直接让输入设备和CPU
交换数据,CPU
把计算好的数据直接输出给输出设备,这样不是更快吗???
就像这样:
在这个没有内存的计算机结构中,我们有输入设备,输出设备,CPU,其中CPU起到计算功能,用于处理计算机的数据。CPU具有极高的运算效率,但是输入输出设备的读取速度是很慢的,因此很多数据刚被读取到CPU中,就立马被计算完了,因此CPU会长期处于闲置状态,这对CPU的计算资源造成了大量浪费。因此我们要想办法提高CPU得到数据的速度,也就是输入输出设备的数据交换的速度。
但是如果想要提高输入输出设备的效率,那么就要用更好的材料和技术来制作这些设备,如果计算机中所有输入输出设备的材料以及技术都达到了CPU级别,那么确实可以让计算机的计算效率不被数据的读取速度影响,但是这将面临计算机成本大幅度提高的问题,有的人工作一辈子也买不起一台计算机。
因此冯诺依曼提出了用内存作为一个中间枢纽的想法:
内存的读取效率介于输入输出设备
与CPU
之间,因此CPU
读取数据的速度,就和内存
输出数据的效率差不多了,只要内存的速度越接近CPU
,那么CPU
的利用率也就越高。
但是这个结构依然有问题,那就是:内存的读取速度又会受到输入输出设备的影响,内存想要从输入设备读取数据,最后的数据传输速度不取决于内存,而取决于输入设备。最后整个计算机的数据传输效率,还不是取决于输入输出设备的传输效率?
理论上来说,确实是这样的,就好像一个木桶,这个木桶能装多少水,不取决于最长的那一块板子,而取决于最短的那一块板子。
其实,冯诺依曼体系结构中,输入设备
向内存输入数据,不是说CPU
现在要计算啥,内存就从输入设备
提取啥。内存会提前预知CPU
要使用的数据,从而预先把它加载到内存中,这样一来,最后整个计算机的计算效率,就取决于内存的数据传输效率了。至于内存是如何预知CPU
需要计算的数据,这是操作系统OS
的工作了。
通过这样一个冯诺依曼体系结构,我们计算机的计算效率就主要取决于内存
和CPU
了,因此电脑厂家只需要把内存
和CPU
的性能提上来,整个计算机的效率也就上来了。其余的部件,都可以用低廉的材料制作,整个计算机的成本降下来的同时,效率还提高了。因此计算机得以走进普通百姓的家中。
OS管理机制
刚刚我们讲明白了计算机的硬件架构,现在我再来讲一讲计算机的软件架构。计算机中,最重要的软件就是操作系统OS
,在整个计算机的软硬件架构中,OS
的定位是一个管理一切软硬件资源的管理者
。
整个计算机的体系结构如下:
OS对下层硬件的管理
最后三层依次是:OS
,驱动
,底层硬件
。
那么操作系统是如何管理硬件的呢?我先来为大家举一个现实生活中的管理案例。
在大学中你很可能都没有见过你的校长,院长等管理层大人物。但是学校可以知道你有没有挂科,你能不能评奖学金等等。那么这些管理层人员,明明都没有见过你本人,是如何管理你这个学生的呢?
他们在管理你的时候,手中会有你的众多数据,比如:入学年份,年龄,招生方式,各科成绩等等。一旦管理层手中有你的数据了,他们就可以根据你的考试成绩来决定你能不能正常毕业;根据你的各项指标,来决定你能不能评奖学金等等。
这个过程中可以发现,管理的本质不在于对你本人做管理,而在于对你的信息做管理。管理者的核心工作,就是根据你的数据来做决策。
操作系统亦然,操作系统想要管理硬件设备,它管理的并不是硬件本身,而是这个硬件的数据。那么下一个问题就来了,操作系统如何得到硬件的信息???
这就涉及到了驱动的工作:
每一个硬件设备,都会有自己的驱动程序,驱动程序内部有众多关于硬件的信息,操作系统通过管理驱动来管理硬件
有的人会发现,当你买了一个新的鼠标,新的键盘,第一次插到电脑上,它都要等待一小会才能使用。而且电脑有可能还会在屏幕上显示驱动程序安装成功这样的提示语句。
其实,每一个硬件在制作的时候,厂家都会在其内部写好一个驱动程序,一旦这个硬件接入到计算机,那么驱动程序就会被操作系统得到,从而进行管理。因此第一次使用一个新的鼠标,键盘的时候,之所以要等一下才能用,就是因为驱动程序还在安装,没有驱动程序,操作系统就无法管理硬件,自然也就无法使用硬件了。
再比如说,有一些硬件,当你接入到计算机后,其可能会提示你:这个设备与计算机不兼容,计算机怎么知道这个设备和计算机不兼容的?这就是因为接入的时候,操作系统得到了硬件的驱动程序,从驱动程序中检测到了这个设备的信息,从而判断出这个设备与计算机不兼容。
至此,我们就已经讲解完了操作系统是如何管理硬件的,以及是如何得到硬件的信息的。那么我们再来看到一个问题:当我们有众多硬件接入到计算机,操作系统是如何对这些硬件批量管理的?
在讲解这个问题之前,我要提出学习操作系统的六字真言,一切操作系统的管理行为,都遵顼以下六字:
先描述,再组织
比如说,操作系统想要管理一个鼠标,于是得到鼠标信息后创建了一个结构体,存储鼠标的各项信息:
struct device { int type; char* name; //... }
比如以上结构体就存储了鼠标的名字,类型等信息。于是操作系统通过管理这个结构体来管理这个鼠标。同样的,键盘,显示器,打印机等等设备,在操作系统中都会有自己的结构体,这个结构体描述了硬件的各种信息,这个过程就叫做描述。
那么操作系统要如何管理这么多结构体?其只需要通过数据结构把这些结构体组织起来即可,比如把这些结构体放到一个链表中,放到数组中,等等。于是操作系通过管理这个链表来管理这一堆结构体,比如说一个鼠标的USB接口被拔掉了,于是操作系统在这个包含了众多结构体的链表中,遍历查找“鼠标”的结构体,然后把这个结构体中描述状态的那个成员,从开启改为关闭。这个把描述硬件的结构体用数据结构连接起来统一管理的过程,就是组织。
至此,我们就以及讲完了操作系统是如何管理硬件的,汇总如下:
- 操作系统通过
驱动程序
来获得硬件的信息,管理硬件 - 操作系统在管理众多硬件的时候,采用
先描述,在组织
的思想,把描述各个硬件的结构体用数据结构组织起来统一管理
OS对上层用户的服务
操作系统管理好硬件,是一种手段,而这个手段的最终目的,是为了给上层提供安全可靠
的服务。
我特意标红了四个字:安全可靠
,那么操作系统又是如何保证自己提供的服务是安全可靠的?我们再看到一开始的计算机体系层次图:
从操作系统向上,依次是系统调用接口,用户操作接口,用户。
请问:==用户可以直接访问操作系统的底层吗?==就拿我们刚刚的例子来说,我们知道每个硬件都有自己的结构体来描述自己,操作系统可以管理这些结构体。那么这些结构体可以直接交给用户管理吗?
很显然,这是很危险的,如果某个用户拿到了一个描述鼠标的结构体,原本这个鼠标是罗技公司生产的,用户直接修改这个结构体里面对厂商的描述,把它修改为了苹果公司生产的鼠标,这可就乱套了。因此操作系统不能把底层直接展示给用户,不然是非常危险的。
但是操作系统又要为用户提供服务,于是操作系统给出了很多系统调用接口,也就是操作系统向上一层。
为了保护操作系统内部的数据,用户只能通过系统调用接口来访问计算机
最开始我们就说过,操作系统要为上层提供安全可靠的服务,而操作系统就是通过隐藏自己的底层,让用户通过系统调用接口来保护自己的数据,进而保证安全的。
系统调用接口再往上就是用户操作接口了,不妨想想,不论你是学习python,c语言,C++,你有直接操作过硬件吗??
其实是有的,比如说python的print函数,C++的cout,C语言的printf函数。这些方法,我们都可以向屏幕输出字符,但是屏幕是一个硬件,想要向硬件输出,就一定要经过操作系统这一层。但是我刚刚说过,用户想要访问操作系统,只能通过系统调用接口。这么一说,难道各个语言的输入输出函数,都叫做系统调用接口吗???
这是否定的,其实语言层面的输入输出函数,本质上是对系统调用接口的再封装。现在市面上的操作系统五花八门,比如Android,iOS,Windows,Linux等等,这些操作系统向上层提供的系统调用接口都是不一样的,但是我们的计算机语言,既可以在Windows中运行,也可以在Linux中运行。
在用户操作接口中,我列举了三个例子:shell外壳,lib,部分指令。
对于C语言来说,printf这个函数就是一个用户操作接口,并且它属于lib,即库的范畴。在printf内部,一定封装了真正的系统调用接口,用户调用printf函数,而在printf函数内部再去调用系统调用接口来访问屏幕这个硬件,进而在屏幕上输出。
为什么要再封装一层用户操作接口呢?
-
用户操作接口
以更加简单的方式向用户提供了服务,比如printf
函数。用户无需学会复杂的系统调用接口
,只需要使用用户操作接口
就可以操控硬件。当然,有能力的人也可以直接调用系统操作接口
。 - 用户操作接口提供了跨平台能力,不论是Linux还是Windows等各种操作系统,都可以使用C语言,C++这样的语言来访问,但是这些操作系统的系统调用接口很可能不一样,因此相同的printf函数在Linux和Windows中封装了不同的系统调用接口,从而使得一个用户操作接口层面的接口,可以在各种在操作系统中使用,这就是用户操作接口的跨平台能力。
当然,用户操作接口还要shell,指令等等,比如说在Linux中使用ls指令,就会在屏幕上显示当前目录下的文件夹,这涉及一个向屏幕显示的操作,因此ls指令内部应该也封装了系统调用接口
再往上就是用户了,通过下层以操作系统为核心的软硬件体系架构,用户现在就可以方便快捷,又安全的形式来使用计算机。
至此,我就已经讲解完了计算机的软硬件体系大框架。
我再为大家回顾一下:
- 底层硬件:遵顼冯诺依曼体系结构,通过内存为枢纽的数据交换,实现了降本增效,使得计算机走入百姓家中
- 驱动程序:操作系统管理硬件的重要手段,操作系统通过
驱动程序
获取硬件的信息,进而实行管理 - 操作系统:计算机体系中的
管理者
,管理各种软硬件资源,遵循先描述,再组织
的重要思想,使得操作系统可以批量管理众多软硬件 - 系统调用接口:为了保证操作系统提供的服务是安全可靠的,通过
系统调用接口
来帮助用户访问计算机,同时保护了操作系统内部的数据 - 用户操作接口:直接通过
系统调用接口
访问计算机会比较麻烦,于是通过用户操作接口
以更加便捷的方式提供服务,并且提供了跨平台的特性,使得计算机的访问方便快捷