目录
- 一、计算机工作原理
- 1.冯诺依曼体系
- 2. CPU执行指令的过程
- 二、操作系统
- 三、进程的概念
- 四、进程的管理
- 五、进程的调度
一、计算机工作原理
1.冯诺依曼体系
现在的计算机大多都遵循冯诺依曼体系结构
CPU: 中央处理器,进行算术运算和逻辑判断,一个计算机中最核心的部分
衡量CPU的重要指标(当然远远不止这两个啦):
- 核心数:可以简单理解为一个核就是一个人干活,多核就是多个人干活
- 频率:CPU的运算速度,可以简单理解为一秒钟执行的指令个数
这两个值越高说明CPU越好
存储器:
-
内存(咱们平时说的内存、运行内存):存储空间小,访问速度快,成本高,掉电后数据丢失
-
外存(硬盘,软盘,光盘,U盘):存储空间大,访问速度慢,成本低,掉电后数据保留
输入设备: 用户给计算机发号施令的设备,如鼠标、键盘等
输出设备: 计算机给用户汇报结果的设备,如显示屏等
存储空间大小:硬盘>内存>CPU
数据访问速度:CPU>>内存>硬盘
2. CPU执行指令的过程
指令相当于你告诉计算机做什么,指令表简化版本
指令 | 功能 | opcode | 操作的地址或寄存器 |
---|---|---|---|
LOAD_A | 从RAM(内存)的指定地址,将数据加载到寄存器A中 | 0010 | RAM(内存)地址(4bit) |
LOAD_B | 从RAM(内存)的指定地址,将数据加载到寄存器B中 | 0001 | RAM(内存)地址(4bit) |
STORE_A | 将数据从寄存器A中写入指定地址中 | 0100 | RAM(内存)地址(4bit) |
ADD | 计算两个寄存器数据的和,并将结果放在第二个寄存器中 | 1000 | 2位寄存器ID、2位寄存器ID |
指令一共有8个bit位,前4位opcode表示操作码,后4位表示操作数也就是要操作的地址或者寄存器。
关于CPU的寄存器:
我们的计算机存储数据主要是依靠内存和硬盘,而CPU在进行运算的时候,首先会把数据从内存中读取到CPU中的寄存器当中,寄存器就是CPU内部存储数据的部分,寄存器的存储空间比内存小,访问速度比内存快,成本高,断电后数据会丢失。
CPU执行指令的过程:
- 读取指令:CPU从内存中读取到指定内容,将指令保存到专门的寄存器中
- 解析指令:对照指令表,解析指令要执行的操作和对应的操作数
- 执行指令:执行指令对应的操作
运行可执行文件(exe)时,操作系统会把exe文件加载到内存中,而exe文件中会包含程序运行的指令和数据
CPU中存在着一个特殊的寄存器:程序计数器,计数器保存了接下来要从哪个内存开始执行指令(初始值在exe文件被加载到内存中就会自动设置好),计数器初始值为0,开始时从0号地址开始执行指令,每执行完一次指令,计数器默认+1,但是遇到跳转类语句(函数调用、if语句、while语句等),会被设为其他值
举个例子(简略版):有一个程序的内存信息如下
地址 | 数据 |
---|---|
0 | 00101110 |
1 | 00011111 |
2 | 10000100 |
3 | 01001101 |
4 | 00000000 |
5 | 00000000 |
6 | 00000000 |
7 | 00000000 |
8 | 00000000 |
9 | 00000000 |
10 | 00000000 |
11 | 00000000 |
12 | 00000000 |
13 | 00000000 |
14 | 00000011 |
15 | 00001110 |
步骤:
1)读取指令:程序计数器为0,读取0号内存地址的内容,
2)解析指令:操作码为0010,操作数为1110,对照指令表为LOAD_A,也就是将1110(10进制为14)这个地址的数据,读取到寄存器A当中
3)执行指令:把14地址的内存的数据读取出来,放到寄存器A中,如图:
执行完毕,程序计数器+1,程序计数器的值变为1,
继续执行地址为1的指令
1)读取指令:读取地址为1的指令
2)解析指令:操作码0001, 操作数1111(二进制为15),对照指令表为LOAD_B,也就是将地址为1111的内存中的数据加载到寄存器B中
3)执行指令:将地址为1111的内存中的数据加载到寄存器B中,如图
程序计数器+1,变成2
执行地址为2的指令:
1)读取指令:读取地址为2的指令
2)解析指令:操作码1000, 操作数0100(二进制为15),对照指令表为ADD,此时操作数分成两部分,表示两个寄存器00表示寄存器A,01表示寄存器B
3)执行指令:3+14=17,将17存入寄存器B中,如图
计数器+1->3
执行地址为3的指令:
1)读取指令:读取地址为3的指令
2)解析指令:操作码0100, 操作数1101(二进制为15),对照指令表为SOTRE_A
3)执行指令:将寄存器A的数据(00010001)写入到地址1101中
计数器+1->4
地址为4的数据为全0,程序结束
二、操作系统
操作系统 = 内核+配套的应用程序
常见的操作系统:Windows、Linux、MacOS、Android、IOS
内核的功能就是:
1、管理硬件设备:硬件厂商会提供相应的驱动程序,操作系统通过驱动程序间接操作硬件设备
2、给软件提供稳定的运行环境,现在的操作系统上一般会同时运行很多程序,操作系统会确保当某个程序出问题了,不会影响别的程序执行(例如,你在写代码正在听网易云音乐,当你的代码出bug了,你的网易云音乐不会停止)
操作系统会给应用程序提供API(接口),让应用程序调用,完成不同的功能
三、进程的概念
进程process(也叫任务task),就是正在执行的应用程序
应用程序有两种状态:
1、未运行:此时是一个躺在硬盘上的exe文件
2、运行中:exe文件会被加载到内存中,并且cpu执行了里面的指令
任务资源管理器中可以查看:
执行进程里的指令需要硬件资源,如下
进程是操作系统进行资源分配的基本单位。
四、进程的管理
简单版本理解:
两个方面:
1、描述:通过C语言的结构体或者C++、Java语言中的类,把一个进程的各种属性描述出来
2、组织:通过某些数据结构(比如链表),把上面的结构体一个一个串起来,并进一步的进行各种增删查改
创建一个进程,就相当于创建了一个结构体,并且插入到链表中;销毁(结束)进程也就是把该进程从链表上删除;查看进程,就是在遍历链表
结构体中包含的关键内容
- PID 进程的标识符:同一时刻,一台机器上一个PID就表示了一个进程,一台机器上PID不会重复,操作系统可以通过PID找到对应的进程
- 一组内存指针:通过这些指针,可以知道进程的指令和数据在哪里(操作系统运行一个可执行程序时,会把exe文件中的指令和数据加载到内存中,这些指针保存着这些地址)
- 文件描述符表(顺序表/数组):描述了进程打开了硬盘中的哪些文件
- 进程状态
- 进程优先级
- 进程上下文
- 进程的记账信息
以上4、5、6、7共同决定了进程的调度,我们单独下文介绍
五、进程的调度
计算机同时存在多个要执行的进程,CPU的每个核心可以执行一个进程(也就是执行里面的指令),但是一台机器CPU拥有的核心数量有限,但是却要执行几乎上百个进程,怎么办?
进程调度解决了以上问题:分时复用
某个时刻CPU运行进程1(其他进程先等着),运行一段时间后,CPU去运行进程2,过一会又运行进程3,以此类推,因为CPU运算速度快,上述切换的速度也快,我们看着就像是多个进程在同时执行,这也叫并发执行
多核心的CPU每个核心之间微观上也能同时执行不同的进程,叫并行执行
现在一般把并发和并行统称为并发,并发编程
下面这些属性,就是用于支持并发执行这个调度过程
-
进程状态,包括以下5个
新建状态:当一个进程被创建,但是未分配内存资源,此时这个进程就处于新建状态;
就绪状态:可以随时被调度到CPU上执行指令的;
运行状态:CPU正在执行某个进程的指令,这个进程就处于运行状态;
阻塞状态:无法被调度到CPU上进行执行(因为要进行其他操作,例如写代码时使用Scanner等待用户输入,如果不去输入,程序会一直卡在这);
终止状态:表示该进程完成了它的执行,与此同时该进程占用的系统资源也被回收
-
进程优先级:进程调度时,有的进程先执行,有的进程后执行,这就是优先级
-
进程上下文:分时复用,一个进程执行一段时间,就要从CPU上调度走,过一段时间又回来,此时需要沿着上次执行的结果继续执行,这个进程离开时,之前执行的中间结果会被相应的寄存器保存起来,用于下次使用,寄存器中保存起来的就叫进程的上下文。可以理解为:打游戏的存档~~当你游戏玩累了,不想玩了,此时可以存档,等下次你再想玩的时候直接读档即可
-
进程的记账信息:在有优先级的前提下,不同的进程利用的系统资源是不一样的,操作系统会统计每个进程在CPU上执行的时间、内存使用情况等,根据这个记账信息,操作系统会进一步调整调度策略,做出优化,确保资源足够让每个进程正常执行