冯·诺依曼体系结构(von Neumann architecture)
我们常见的计算机,如笔记本。我们不常见的计算机,如服务器。大部分都遵守冯·诺伊曼体系。
这种体系结构的核心思想是将程序指令和数据存储在同一存储器中,并通过控制单元来协调各个部件的工作。
-
输入设备(Input Devices):
- 这是用户与计算机交互的起点。输入设备可以是键盘、鼠标、触摸屏、网卡、磁盘、摄像头等,它们将用户的操作转换为数据信号,传送给计算机内部。
-
存储器(Memory):
- 存储器是计算机的“记忆”部分,用于存储数据和程序指令。在冯·诺依曼体系结构中,数据和指令存储在同一存储器中,这意味着CPU可以读取存储器中的任何内容,无论是数据还是指令。(存储器就是内存,就是内存!!!我们喜欢称磁盘是外存,就是外部存储)
-
运算器(Arithmetic Logic Unit, ALU):
- 运算器是执行所有算术和逻辑运算的核心部件。它执行加法、减法、乘法、除法以及逻辑运算(如AND、OR、NOT)等。
-
控制器(Control Unit):
- 控制器是计算机的“大脑”,它负责解释存储器中的指令,并协调运算器、存储器和输入/输出设备的工作。控制器通过发出控制信号来指导其他部件执行特定的操作。
-
中央处理器(Central Processing Unit, CPU):
- CPU是计算机的心脏,它包含了运算器和控制器。CPU负责执行程序中的指令,处理数据,并控制计算机的其他部件,当前的CPU就比较丰富了。
-
输出设备(Output Devices):
- 输出设备是计算机与用户交互的终点。它们将处理后的数据转换为用户可以理解的形式,如显示器、打印机、扬声器、磁盘、网卡等。
-
数据信号和控制信号:
- 数据信号(红色箭头)表示在计算机内部流动的数据,如用户输入的数据、程序执行过程中产生的数据等。
- 控制信号(黑色箭头)是控制器发出的指令,用于指导其他部件如何操作。
在冯·诺依曼体系结构中,程序的执行过程大致如下:
- 输入设备将用户的操作转换为数据信号,传送给存储器。
- 控制器从存储器中读取指令,解释指令,并发出控制信号。
- 运算器根据控制信号执行相应的运算。
- 运算结果可能被存储回存储器,或者通过输出设备展示给用户。
我们将所有的输入设备和输出设备统称为外设,输入将外设数据读到内存当中,输出将内存里的数据输出到对应的外设当中。在这里有两个设备比较特殊:网卡还有磁盘,我们谈一下磁盘:
在C/C++当中,我们进行文件读取的时候,读文件就是把磁盘里的数据读到内存当中,写文件就是把内存里的数据写到我们对应的磁盘上,我们将这种读写的动作称为IO(Input/Output),所以这种设备不能严格来说的只是输出设备或者只是输入设备,有可能既是输入设备,也是输出设备,所以我们有IO的概念(IO概念的简单铺垫)
我们知道:
我们编译好的软件,他要运行,必须要先加载到内存,那么在程序运行之前,在哪里?
因为程序就是文件,程序就是我们编译好的,在指定路径下的二进制文件,所以在程序运行之前,是在磁盘上的。
因为CPU的获取,写入,只能从内存中来进行!软件运行其实是CPU执行我们的代码,访问我们的数据,这也是为什么我们编译好的软件,他要运行,必须要先加载到内存。这是由体系结构所确定的。(数据层面:外设->内存->外设,CPU<=>内存)(这也是为什么会有缓存区这一概念,printf为什么不会直接输出到外设)
还有一个问题:
我们为什么不直接从外设->CPU->外设呢?
这里我们需要了解一下:存储分级:
实际上我们计算机里有各种存储设备,寄存器是离CPU最近的,离得越近,存储空间越小,当然也越贵,效率当然也是越来越高。
直接从外设到外设没有CPU的存储分级体系参与,无法充分利用缓存等高速存储来优化数据传输和处理,导致数据传输效率低、处理复杂度高,而CPU的存储分级体系可以有效协调外设数据传输,提高系统整体性能。
这种体系结构的特点是简单、直观,易于理解和实现,但它也存在一些局限性,比如数据和指令的带宽共享可能导致性能瓶颈。随着技术的发展,现代计算机体系结构在冯·诺依曼体系的基础上进行了多种优化和改进。
操作系统(Operator System)
概念(是什么?)
一个基本的程序集合,称为操作系统(OS),操作系统是一款软硬件管理的软件。
操作系统包括:
- 内核(进程管理,内存管理,文件管理,驱动管理)(狭义上的操作系统)
- 其他程序(例如函数库,shell程序等等)
设计OS的目的(为什么?)
1.软硬件体系结构是层状结构,体现的是高内聚,低耦合 :
软硬件体系结构的层状结构通过将系统分解为具有明 确职责的层次,实现了高内聚,即每个层内部的功能紧密相关,专注于完成特定的任务。同时,这种结构也实现了低耦合,层与层之间的依赖性降低,它们通过定义良好的接口进行交互,从而减少了层间直接的相互影响。这种设计提高了系统的可维护性和可扩展性,使得各个层可以独立地进行开发和优化。
就是之前我们没有学习函数的时候,将代码全部写到main函数里面,这就不具有高内聚,低耦合的特点,之后,我们将main函数当成调用层,调用对象是函数体,就是实现层,这就具有了高内聚,低耦合的特性。
在我们电脑坏了的时候,正常情况下并不需要直接换电脑,而是换电脑的某个硬件,所以不仅仅在软件层面是有高内聚,低耦合的特性,在硬件层面上也是。
2.访问操作系统,必须使用系统调用--其实就是函数,只不过是系统提供的。
在我们的软件层,出现了一个system call,操作系统不允许用户直接访问内存,直接读取进程,直接访问文件,直接读取驱动,操作系统他必须要求用户通过操作系统自己提供的一些C封装的接口来访问操作系统,这个接口称为系统调用。
我们的printf的本质是将我们的数据写到了硬件上,显示器!但是不是我们写的C程序直接直接写到了硬件上,因为我们整个计算机体系,不管是Linux还是Windows,都是层状的,我们自己做开发,我们使用C标准库中的方法,而我们用到的C标准库当中的方法,最终我们到达了将数据写到显示器上的客观事实,而我们是不可能绕过操作系统直接去到硬件的,所以本质上,printf这个函数,他的底层一定要封装系统调用,然后通过操作系统,对驱动进行访问,访问对应的驱动,然后才把我们的数据交到硬件上。像我们学过的scanf等等关于IO操作,文件操作的等,全部都要贯穿操作系统!!!
总结:我们的程序,只要你判断出他访问了硬件,那么他必须必须贯穿整个软硬件体系结构(上图)。还有,库可能在底层封装了系统调用。
如何理解管理
在整个计算机软硬件架构中,操作系统的定位是:⼀款纯正的“搞管理”的软件,这也是操作系统的核心功能,“搞管理???”,那我们该如何去理解管理?
-
管理的普遍性:无论是在学校还是企业,管理都是确保组织运作顺畅的关键。
-
管理的层级结构:从校长到辅导员,再到学生,每个层级都有其管理职责,体现了管理的层级性。
-
管理的组织结构:通过层级,管理涉及到对信息和资源的组织,确保从顶层到底层的有序流动。
-
管理的实践:有效的管理需要清晰的结构和流程,正如学生信息节点的有序排列。
-
管理与技术:在计算机领域,操作系统通过数据结构(如struct+链表等)来描述和管理硬件资源,体现了管理在技术实现中的重要性。(增删查改)
操作系统怎么管理所有硬件的?
每一个硬件都有硬件名,操作系统怎么管理硬件的,硬件名,硬件状态,硬件其他的属性,操作系统可以在自己操作系统内部先描述再组织,把网卡,硬盘,显卡,键盘,显示器统一可以使用struct_devise定义一个类,类里面可以包含每种硬件的各种属性,其中,我们的属性包括硬件的名称,硬件的状态,硬件相关的链接信息,所以在操作系统内,构建struct_devise这样的结构,每一个设备都要对应一个struct_devise这样的对象,把这样的对象管理起来,所以操作系统管理硬件转化成了对链表的增删查改。
操作系统怎么对进程做管理的?
目前,我们还没有学过进程,那么操作系统怎么对进程做管理?答案是:操作系统首先要对每个进程定义struct结构体对象,然后把进程相关的属性放在结构体里,里面添加属性,用链接节点将全部连起来,操作系统管理进程转化成对链表的增删查改。(对文件管理,网络管理完全是一样的先描述再组织)
所以如今管理就是先描述再组织,这也就是为什么我们学习的C++(还有Python,Java等等)会有类,STL的概念。类解决了先描述的问题,STL解决了再组织的问题!!!
系统调用和库函数概念
操作系统要向上提供对应的服务,但是操作系统,不相信任何用户或者任何人。
这句话就很矛盾:你不相信我,你还给我提供服务。这其实在现实生活中也有存在这种组织,就是银行。银行给我提供存钱,理财等的服务,但是银行是不相信我的,不相信我有这表现:
不让我进入银行后端的银库里面,不允许让我的钱放入他的盒子里面,我要取钱不能进入银行的仓库去取钱,万一我多拿了,那可怎么办?
所以银行会有一窗办理:
银行不相信我们任何人,但是需要给我们提供服务,所以有了一窗办理,也就是操作系统中的系统调用。
上文提及系统调用本质就是操作系统给我们提供的函数调用,比如我们未来将要学到的:
man fork
man waitpid
man socket
这些都是操作系统为我们提供的系统调用,我们未来想要访问操作系统,获取操作系统中的数据,设置自己的信息等,全部都是通过系统调用完成的。
像我们的Linux/Windows/Mac OS等,基本都是由C语言写的,所以为我们提供的系统调用基本都是C函数。
既然是函数,那么大部分(60%~70%)有输入参数和返回值,那么输入参数就是用户提供给操作系统的,返回值对应的就是操作系统给用户的。实际上我们去银行取钱,要将需要的个人信息,物品通过窗口给到工作人员,这就相当于我们将参数传给银行内部的系统了,然后银行内部的系统,在自己的系统的运作之下,银行的系统内部会将结果返回,所以用户就成功取到了。(系统调用本质就是用户和操作系统之间进行某种数据交互)
- 在开发⻆度,操作系统对外会表现为⼀个整体,但是会暴露⾃⼰的部分接⼝,供上层开发使⽤,这部分由操作系统提供的接⼝,叫做系统调⽤。
- 系统调⽤在使⽤上,功能⽐较基础,对用户的要求相对也⽐较⾼,所以,有⼼的开发者可以对部分系统调⽤进⾏适度封装,从⽽形成库,有了库,就很有利于更上层用户或者开发者进⾏⼆次开发。
库函数和系统调用属于上下层的关系。