一.冯诺依曼体系结构
我们所使用的计算机,如笔记本等都是按照冯诺依曼来设计的:
截止目前,我们所知道的计算机都是由一个一个的硬件组装起来的,这些硬件又由于功能的不同被分为了输入设备,输出设备,存储器和cpu。
输入设备有:键盘,鼠标,话筒,摄像头,网卡,磁盘等等……
输出设备有:显示器,网卡,磁盘,打印机等等……
而存储器其实就是我们所说的内存,而CPU是由运算器和控制器组成的。
下面我们在谈的时候先不管控制器,只观察运算器:
1.cpu只与内存打交道
软件其实就是一个二进制程序,而软件被运行前必须加载到内存中,那没被加载到内存中在哪呢?就在磁盘中。就比如QQ这个软件它在没有运行的时候就在磁盘中,我们双击即使将其加载到内存的动作。
那为什么必须要将软件加载到内存中呢?因为体系结构规定!因为在冯诺依曼体系结构中,cpu只能与内存交互,无法直接与外设交互,所以我们必须得将程序先加载到内存中,才可以被cpu执行。
在加载的过程中,数据(代码和数据)就发生了流动,但是流动这个概念很模糊,简单来说,就是将数据从一个设备拷贝到另一个设备的过程。
所以一个体系结构的效率也就体现在了拷贝的效率上。
综上,在数据层面上,cpu只与内存打交道,内存只与外设打交道。
2.理解数据流动
比如我们要打印一个字符串到到屏幕上,此时当我们运行程序,程序就会等待外设——键盘输入,输入一个字符串之后,加载到该程序中,然后通过cpu的处理,最后返回到内存中,最后转交给输出设备——屏幕。这样就达到了我们打印信息的目的。
下面举一个发送qq消息的例子:你和你的同学放寒假在家使用电脑qq聊天,你发送了一个你好,同时在对方屏幕上也出了一个你好,这也是是一个数据流动,那么这到底是怎么实现的呢?
其实利用电脑聊天本质上就是两台冯诺依曼体系通过网络在进行数据流动:
你首先双击qq将其加载到内存中,然后通过输入设备键盘将你好输入到聊天框中,此时点击发送,你好这条消息首先交到了qq中,也相当于交到了内存中,再交到cpu中,进行加密等一系列操作,最后返回到内存中,交给输出设备网卡,网卡通过网络,将其发送到你朋友的机器上。而对于你朋友来说,他的输入设备就是网卡,接着网卡将数据交给内存,内存交给cpu,cpu进行解码等操作,返给内存,最后内存将数据通过输出设备屏幕将信息你好显示出来。
当然,这条你好不仅他能看见,你也能看见,这就说明对你来说,你的输出设备不仅有网卡,也有显示器。
二.操作系统
操作系统其实是一款进行软硬件管理的一款软件。
不论是Linux还是Windows还是macos都是操作系统,它们的功能都是类似的,都是要进行管理软硬件。
但是狭义上的操作系统指的是操作系统内核,但是内核不允许任何人直接访问,所以一些大佬就对操作系统进行了封装,设计出了一些外壳程序——shell等,这样就可以帮助用户与内核建立联系。
1.设计OS的目的
我们先前说了,操作系统是一个进行软硬件管理的软件,所以它是处在软件层和硬件层的中间,一遍向下与硬件交互,管理所有的软硬件资源,向上,为用户提供一个良好的执行环境。
我们看,计算机上面的硬件和软件都是层状分布的,这样符合高内聚低耦合的设计思路。即同一模块之间的联系紧密,但不同模块之间的影响很小,一个产生问题不会对另一个产生影响。
而操作系统的位置是一个承上启下的位置。当我们需要访问硬件时,操作系统会调用驱动系统,驱动程序让硬件处于工作状态,这样就能保证与硬件的交互,但与硬件的交互不是目的,而是手段。
当用户需要访问操作系统时,不可以直接访问,而是要通过系统调用,系统调用其实就是系统提供的一系列函数。
而在系统调用层上面还有一层用户操作接口,这些接口一些在底层封装了系统调用,这下开发者在实际开发过程中,便不需要亲自进行系统调用,而是借助已有的库进行开发。
例如我们在C语言学到的printf函数,该函数在底层就有可能封装了系统调用,因为其向硬件——显示器打印了内容。我们可以简单的认为,如果一个程序访问了硬件,那么这个程序必须贯穿整个软硬件体系结构。
综上所述,设计OS的目的其实就是为了给用户开发者一个舒适简单的开发环境。
2.理解操作系统如何进行管理
我们已经知道,操作系统是一个进行软硬件管理的软件,所以我们自然要明白操作系统是如何进行管理的。
先描述,在组织。
下面举一个简单的例子,比如大学校园,现在只有三类人:学生、导员和校长。校长要对学生进行管理,校长就是管理者,而我们学生就是被管理者。那么我们要怎么进行管理呢? 我们对学生管理到底是在管理什么呢?
其实校长对学生进行管理只需要对学生的数据进行管理,这个学生叫什么,多大,什么专业,家是哪的等等……所以校长就可以设计一个excel表格,表头就是学生的信息。但是校长需要去每一个学生的宿舍让学生填表么?当然不用了,这时候就需要导员出场了,导员就好比驱动程序,校长发布决策,导员执行决策——让学生填表。
但是这样虽然有了学生的信息,但是人一多的话,校长管理起来依旧麻烦,校长需要遍历excel表格来获取信息,这样太耗时了。
所以我们可以借助计算机来进行管理,我们学过结构体的概念,我们可以将学生的信息用结构体来表示。这下如果我们要新增一个学生,就可以新增一个该类的对象,开除一个学生就删除一个变量。这就是描述的过程:
struct student
{
string _name;
int _age;
string _id;
string _adderss;
// ...
};
但是如果有1万个学生就有1万个变量,这样很难维护,所以我们可以给类中加一个struct student* next指针,使一个一个的学生成为一个节点,用链表的方式连接起来,这就是组织的过程。
这样,校长之前翻看excel表格的行为,就转变成了对链表的增删查改。
3.理解系统调用
系统调用时用户与操作系统进行交互的桥梁。因为操作系统本质上不相信任何人,所以它干脆不允许任何人访问。但是它又不得不让人访问,所以就做出了一系列的系统调用让用户使用。
这样的情形很像银行这一角色。银行本质上就不相信任何人,所以它不允许任何人去直接访问它的系统与金库。但是它又得提供它的一些服务,所以设计出了窗口这样的东西。这些窗口就像是系统调用。
虽然有了窗口,但是去银行的难免有人不会知道操作顺序,所以银行一般还有大堂经理这一角色。
当我们不知道怎么操作时,就可以寻求大堂经理的帮助,大堂经理就会帮助我们去往窗口进行操作。他的角色就好像系统调用上一层的用户调用层,比如一些库,指令,shell外壳等等。它们可以帮助我们去进行系统调用。