计算的需求在⼈类的历史中是广泛存在的,发展大体经历了从⼀般计算⼯具到机械计算机到目前的电子计算机的发展历程。人类对计算的需求,驱动我们不断的发明、改善计算机。目前这个时代是“电子计算机”的时代,发展的潮流是:更快速、更稳定、更微型。
推荐大家看《计算机简史》,这里就不过多介绍了 。
现代的计算机, ⼤多遵守 冯诺依曼体系结构。
认识计算机的祖师爷 -- 冯诺依曼冯·诺依曼(John von Neumann,1903年12⽉28⽇-1957年2⽉8⽇), 美籍 匈⽛利 数学家、 计算机 科学家、 物理学家 ,是 20世纪 最重要的数学家之⼀。冯·诺依曼是 布达佩斯大学 数学博⼠,在现代 计算机 、 博弈论 、 核武器 和 生化武器 等领域内的科学全才之⼀,被后⼈称为“现代计算机之父”、“ 博弈论 之父”.
从功能方面看,CPU的内部由以下四部分组成:
所谓指令,即指导 CPU 进行工作的命令,主要有操作码 + 被操作数组成。其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也可能是寄存器编号等。指令本⾝也是⼀个数字,用二进制形式保存在内存的某个区域中。
接下来,我们演示指令运行的⼀个周期 :
CU:控制单元,ALU:算术逻辑运算单元
我们可以得到指令周期:取指令-->分析指令--> 执行指令
小结:
所谓程序,就是⼀组指令以及这组指令要处理的数据。狭义上来说,程序对我们来说,通常表现为⼀ 组文件。程序 = 指令 + 指令要处理的数据。
为了提升编程效率,最早创造了汇编语⾔的概念。其实汇编语⾔和机器语言(也就是指令)直接是完全⼀⼀对应的,只是相对于 0、1 这些数字,发明了⼀些帮助⼈类记忆和理解的符号将其对应起来,也就是我们上面看到的类似 LOAD_A、LOAD_B 等。程序员完成编程之后,需要使⽤汇编器 (assembler)将汇编语言翻译成机器语言。虽然汇编降低了程序员的记忆成本,但要求程序还是必须掌握计算机硬件的所有知识,而且随着计算机厂商越来越多,⼀次编写的程序往往只适用于⼀类计算机。这个是远远不够的,所以更为高级的语⾔诞生了,高级语言屏蔽了硬件细节,让程序员可以站在更高的层⾯上思考自己的业务。这⾥以 C 语言为例,程序员完成程序的编写之后,需要使⽤编译器(compiler)和连接器(linker)将程序翻译成汇编语⾔,再借助汇编器变成最终的机器语⾔。借助封装的思想,我们学习编程变得越来越容易。不过有利则有弊,⾼度的抽象,导致很多的程序员把计算机视为⼀个⿊箱,完全⽆法理解⾃⼰的程序是如何⼯作起来的。
注意:⾼级语⾔的⼀条语句(Statement)往往对应很多条指令(Instruction)才能完成。
操作系统的两个基本功能:
每个应⽤程序运⾏于现代操作系统之上时,操作系统会提供⼀种抽象,好像系统上只有这个程序在运⾏,所有的硬件资源都被这个程序在使⽤。这种假象是通过抽象了⼀个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之⼀。
PCB中的一些核心属性:
进程经常要访问硬盘。操作系统对于硬盘这样的硬件设备,进行了封装,抽象为”文件“,按照”文件“的方式来操作。
一个进程要想操作文件,需要先”打开文件“:就是让进程在文件描述符表中分配一个表项(构造一个结构体)表示这个文件的相关信息。
我们假设CPU是一个舞台,要执行的指令(进程要执行指令)是一个演员。一个CPU可能有一个核心,也可能有多个核心,每个核心都是一个舞台,演员需登上舞台才能表演,同一时刻,一个舞台上只能有一个演员(进程)!
如果一个电脑的CPU有16个核心,但系统上的进程远远不止16个,这时候就不够分了!这就涉及到一个非常关键的概念——分时复用(并发)。
也就是让演员轮流上场。
对于单核CPU:
单核CPU也能支持一个“多任务操作系统”的运行。这就是用到了“分时复用(并发)”。
CPU的核心只有一个,先执行进程1的代码,执行一会儿后,让进程1下来,进程2上;进程2执行一段时间后,换进程3,以此类推。
只要切换速度足够快,人们是感知不到这个切换的过程的,在人眼看起来,多个任务/进程就是“同时执行”的。对于CPU频率,都是多少GHz,一秒钟执行几十亿条指令!意味着,短时间内,CPU就可以进行很多次的进程切换,只要速度够快,人们就感知不到。当然也会存在极端情况,比如系统的进程太多,负担太重,就会出现卡顿的现象。
对于多核CPU:
多核CPU的产生,同时执行进程就变得更加复杂。
假设有一个四核CPU,同时就可以有四个不同的进程,在各自的“舞台”上进行执行,此时,微观上,这几个进程也是“同时执行”的,而不是靠快速地切换模拟的“同时执行”(单核CPU),这时也称为“并行执行”。但是针对每个核心,前面的“并发执行”也依然存在。
当前现代的计算机的执行过程,往往是并行+并发同时存在的, 因此,往往将“并行”和“并发”统称为“并发”,对应的编程方式,称为“并发编程”:解决一个问题,同时搞多个任务来执行,共同协作解决问题。
对于实现进程调度,就需要PCB提供一些属性,来支持系统完成对这些进程的调度。以下属性:
每个进程在运行过程中,就会有很多的中间结果,在CPU的寄存器中。
存档:在进程调度出CPU之前,把当前CPU寄存器中的这些信息,给单独保存到一个地方。
读档:在该进程下次再去CPU上执行的时候,再把这些寄存器的信息给恢复回来。
操作系统对内存资源的分配,采⽤的是空间模式⸺不同进程使用内存中的不同区域,互相之间不会干扰。