任何事物的发展都是从需求开始的,那么计算机的出现是为什么呢?让我们先通过计算机发展史,认识一下计算机。
计算机发展史
弹道导弹,国之重器。这对国家的军事是非常重要的。
计算机最初就是用于计算弹道导弹的轨迹。
专用计算机
埃尼阿克,1946年诞生于美国普林斯顿大学,本身就是用于计算弹道轨迹的,计算速度(CPU主频):5000hz,重达几十吨,占地位置非常大。
通用型计算机
图灵提出愿景,冯诺依曼设计实现。
冯诺伊曼体系,由冯诺依曼提出:
CPU:计算机最核心部分,进行算数运算和逻辑判断。
输入设备:把数据交给计算机,比如:键盘、鼠标、麦克风、摄像头。
输出设备:不数据输出为其他东西,比如:显示器、音箱。
有的设备既可以输入也可以输出:比如触摸屏、网卡。
显卡(GPU):显卡的定位和CPU类似,CPU通用计算芯片,GPU专用计算芯片,CPU什么都能算,GPU只能算一种。
CPU简单工作原理
cpu使用逻辑门-门电路的原理。输入的是1或0的比特位,借助于这些门电路,计算出“与、或、非”的值。
门电路分为:与门、或门、非门、异或门(通过前面那些门电路组合而成,相同为0,相异为1)。
这些门电路,借助于二极管等设备的特殊物理特性。
基于这些门电路,组合成半加器(两个比特位相加)和全加器(3个比特位相加)。
进一步构造出加法器(两个二进制数字相加,算加法、减法、乘法【连续相减】、除法【连续相加】)。
编程语言
计算机比较“笨”,他不会像人一样理解语言,所以就有了编程语言。
世界上编程语言种类繁多,分为三个类:
1.机器语言
二进制(01)构成的指令,计算机认识。
厂商设计CPU的时候就会设计好“指令集”,CPU都理解哪些指令,以及这些指令要怎么工作。(类似CPU向我们提供了API)。
2.汇编语言
人类不太容易理解机器语言,于是,基于机器语言的基础上,出现了汇编语言。
通过简单的单词作为“助记符”,代替二进制指令。
每一个机器指令,对应到一条汇编语句。
备注:
不同的CPU有不同的体系架构,支持的指令集不一样。即使是同类架构,不同的版本,指令集也是不一样的,导致了汇编语言会不一样。如果读者学习汇编语言的话,一定要明确学习的是针对哪个系列的CPU!
3.高级语言
高级语言是基于汇编语言更高一级的封装,更接近于人类的语言和逻辑,具有可读性(这里是笔者的理解)。
比如我们常见的:C语言、C++、C#、Java等...
操作系统
操作系统是一个用来管理的软件,用于软件、硬件、用户三者的交互:
1.对下,要管理硬件设备。
2.对上,要给软件提供稳定的运行环境。
常用操作系统
Windows:98、2000、XP、vista、win7、win10、win11...
Linux(特别适合于开发和部署):服务器、嵌入式设备(冰箱,洗衣机,投影仪之类)、移动端设备...
Mac:苹果电脑用的系统(和Linux系统表兄弟)。
Android:本质上也是Linux。
IOS:和Mac同宗同源。
操作系统定位
硬件设备:电脑后盖打开,看到的就都是硬件设备。
驱动程序:硬件设备种类非常多,厂商在开发硬件的时候会提供驱动,安装驱动后系统才能正确识别硬件。
操作系统内核:操作系统的核心功能。
系统调用:操作系统给应用程序提供的API。比如:一个程序需要操作硬件,需要通过系统调用,把操作命令告诉系统内核,内核调用驱动程序,进一步操作硬件。
应用程序:比如我们使用Java写的程序。
进程
什么是进程?
一个跑起来(运行中)的程序,就是一个进程。进程(process)也叫做任务(task)。
没有运行的,不是进程!
进程(process)也叫做任务(task)。
job这个术语比进程更抽象,process是解释job的一种具体实现,job不一定是process。
每一个进程都对应一些资源。进程是操作系统分配资源的基本单位。
总结:进程是一个重要的软件资源,是由操作系统内核负责管理的。
什么是句柄?
句柄是另一个术语handler,系统包含很多的软件资源(进程就是一种软件资源)。而这种软件资源是在操作系统内核中,代码不方便调用,这时我们就使用到了句柄(简单的整数/编号),它起到遥控器的作用,帮助代码调用软件资源。
如何描述和组织进程?
描述:使用一个结构体(c语言的结构体)来描述进程属性(操作系统基本都为c语言或者c++)
用来描述进程的结构体,叫做PCB(进程控制块),这是一个结构体,不是“PCB板”。
组织:通过双向链表,把多个PCB串到一起。
创建一个进程,本质上就是创建一个PCB这样的结构体对象,把它插入到链表中。
销毁一个进程,本质上就是把链表的PCB节点删除掉。
任务管理器查看到进程列表,本质上就是遍历链表。
PCB里面有哪些描述了进程的特征?
1.pid:进程的身份标识(唯一数字)。
2.内存指针:指向自己持有的内存资源。
3.文件描述符表:硬盘上的文件等其他资源。
内存指针和文件描述符表描述了进程持有哪些硬件资源。
4.进程调度相关属性:
(1)进程的状态
就绪状态:随叫随到,进程准备好了随时去CPU执行。
运行状态:正在CPU执行的。很多操作系统不会明确区分就绪与运行。
阻塞状态:短时间无法到CPU执行。比如进程在执行密集的IO操作,读写数据。
(2)进程的优先级
比如给排工作量,先给谁排,后给谁排,给谁排多点,给谁排少点。
进程也是有优先级,操作系统并不是一碗水端平。
(3)上下文
操作系统在进行进程切换的时候,就需要把进程执行的“中间状态”进行记录,下次这个进程再次上CPU运行的时候就可以恢复上次记录的状态,继续执行。就好像游戏“存档,读档”。
进程的上下文就是CPU中的各个寄存器的值,保存的就是程序运行过程中的中间结果。
保存上下文,就是把CPU各个寄存器的值,记录保存到内存中。
恢复上下文,就是把内存中寄存器值恢复回去。
(4)记账信息
操作系统统计每个进程在CPU上占用的时间和执行的指令数,根据这个来决定下一阶段怎么样调度。
CPU的“分时复用”
并行:微观上同一时刻,两个核心上的进程,就是同时执行的。
并发:微观上同一时刻,一个核心只能运行一个进程,但能对进程进行快速的切换。宏观上人感知不到,就好像许多进程同时进行。
内核负责处理并行和并发,程序员感知不到,所以把并行和并发统称为并发。
内存管理
内存是个啥东西?
类似于excel表格,每一个表格都有编号可以确认位置。
内存(物理上是一个内存条)可以存很多数据。“表格的编号”就是“内存地址”,这个地址也被称为“物理地址”。
内存条上面,有“内存颗粒”,内部的结构,也是一系列门电路,构成了很多的数据存储单元。
内存特性
随机访问,访问内存上的任意地址的数据,速度都极快,时间上都差不多。正是这个特点,造就了数组取下标操作是O(1)。
虚拟地址空间
程序中获取到的内存地址,并非是真实的物理内存的地址,而是经过了一层抽象,虚拟出来的地址。由操作系统和专门的硬件设备(MMU 很多时候集成在CPU)进行虚拟地址到物理地址的转换。
进程访问内存越界的时候,操作系统发现无法将虚拟地址转换为物理地址,就会和进程反馈错误(具体来说就是发送一个SIGN SEGEMENT FAULT的信号,引起进程崩溃)。哪个进程出BUG,哪个进程崩溃,都不会对其他进程有影响。
操作系统为我们提供了一些特殊的系统调用,就可以手动操作另一个进程的内存数据了。
解决进程之间相互影响的问题
虽然进程隔离了,但是又引入了新问题。
有些时候进程之间需要进行数据的交互。(相互配合)
在隔离性的基础上,开个口子。进程间通信,有很多方式,核心思路都是创建一个多个进程都能访问到的“公共空间”,基于这个“公共空间”来进行交互数据即可。