简单介绍计算机的工作过程
目录
前言
一、CPU的基本工作流程
1. CPU 指令的执行过程
2. CPU指令执行需要关注的细节
二、简单理解操作系统
1. 操作系统的作用
2. 进程
1. 进程在系统中管理的两个步骤
2. PCB 的核心属性
3. 进程的内存管理
4. 进程间通信
前言
本文主要介绍了CPU的基本工作原理和操作系统中进程管理的核心概念。CPU执行指令的过程包括取指、译码和执行三个阶段,需要关注指令集、操作数和执行效率等问题。操作系统的作用在于管理硬件设备和提供稳定的软件运行环境。进程作为系统资源分配的基本单位,其管理涉及描述(PCB)和组织(链表)两个步骤。PCB包含PID、内存指针、文件描述符表等核心属性,支持进程调度和并发执行。进程间通过公共空间进行通信,而内存管理则保证各进程内存空间的独立性。文章通过具体示例和概念解析,帮助读者理解计算机系统的基本运行机制。
一、CPU的基本工作流程
1. CPU 指令的执行过程
以面指令表为例:
指令 | 功能说明 | 4位 opcode | 操作的地址或者寄存器 |
LOAD_A | 从RAM的指定地址,将数据加载到A寄存器 | 0010 | 4位RAM地址 |
LOAD_B | 从RAM的指定地址,将数据加载到B寄存器 | 0001 | 4位RAM地址 |
STORE_A | 将数据从A寄存器写入到RAM的指定地址 | 0100 | 4位RAM地址 |
ADD | 计算两个寄存器的数据和,将结果保存到第二个寄存器 | 1000 | 2位的寄存器ID 2位的寄存器IDID |
注意:寄存器 A 为 00,B 为 01;
指令的运行周期:
地址 | 数据 |
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 |
假设从地址 0 的位置开始执行:
- 读取指令:00101110;
- 解析指令:opcode 为 0010,内存地址为 1110;
- 执行指令:将内存地址 1110 的值(3)放到寄存器 A 中;
- 读取指令:00011111;
- 解析指令:opcode 为 0001,内存地址为 1111;
- 执行指令:将内存地址 1111 的值(14)放到寄存器 B 中;
- 读取指令:10000100;
- 解析指令:opcode 为 1000,寄存器的 ID 分别为 01 和 00;
- 执行指令:将寄存器 01(14) 和 00(3) 的值累加放到寄存器 00 中(17);
- 读取指令:01001101;
- 解析指令:opcode 为 0100,内存地址为 1101;
- 执行指令:将寄存器 A 的值保存到内存地址 1101(17);
2. CPU指令执行需要关注的细节
- CPU要执行的指令是在内存中的(冯诺依曼体系结构的基本设定是让执行单元和存储单元解耦合);
- CPU要想执行指令,需要先从内存中取指令,再解析指令,之后再执行指令;
- 取指令需要从内存中读取指令到 CPU 寄存器中,取指令操作非常耗时,读取内存相对于 CPU 计算,开销大得多,因此 CPU 通过缓存,流水线等技术优化这里的效率;
- CPU 解析指令需要用到指令表,不同架构的 CPU 支持的指令表不同(x86 和 arm 是不同的),指令表的细节保存在 CPU 中,CPU 很容易识别;
- 指令在执行的过程中会带一些操作数,不同的指令操作数的含义不同;
- CPU 的重要参数,主频,可以近似看成一秒钟 CPU 可以执行的指令数个数;
二、简单理解操作系统
1. 操作系统的作用
操作系统的主要作用有两方面:
1. 统一管理硬件设备;
2. 给其它软件提供稳定的运行环境;
由于不同 CPU 的指令集是不同的,操作系统提供的 API 也是不同的,通常程序不能跨平台使用;
但是 JAVA 的虚拟机在操作系统 API 的基础上又进行了封装,能够支持 JAVA 程序跨平台使用;
多任务操作系统:指的是同一个时刻可以运行多个任务;
单任务操作系统:同一时刻只能运行一个程序;
目前所使用的操作系统,大多属于“多任务操作系统”;
2. 进程
进程是操作系统提供的一种软件资源;
进程是系统分配资源的基本单位;
操作系统的任务和进程是等价的,任务就是进程;
1. 进程在系统中管理的两个步骤
1. 描述
通常是使用类或者结构体的形式,把进程的属性都列出来;
操作系统是使用 C/C++ 实现的,因此可以使用结构体来把进程的属性都列出来;
表示进程信息的结构体,也叫做 PCB(Process Control Block);
在 Linux 上,PCB 是一个叫做 task_struct 的一个结构体;
2. 组织数据
使用一定的数据结构,把这些结构体/对象,组织起来;
在 Linux 中,使用链表这样的数据结构把若干个 task_struct 连起来;
当我们看到任务管理器中查看进程的时候,就是操作系统遍历链表,并展示主要信息的过程;
如果运行一个新的程序,系统就会多出一个进程。新增加的这个程序对应一个新的 PCB,并且把这个 PCB 加入到链表中;
如果程序运行结束退出程序,就会把对应的 PCB 从链表上删除,并释放对应的 PCB 资源;
实际中的操作系统,是一个更加复杂的链式结构,不仅仅是一个简单的单链表;
2. PCB 的核心属性
PCB 是一个非常庞大的结构体,每个结构体有上百个属性,下面介绍几个核心的属性;
PCB 中的核心属性:
PID 表示进程的身份标识:
- PID 是一个简单的不重复的整数,类似数据库中表的自增主键;
- 同一台机器上,同一时刻,每个进程的 PID 是不重复的;
内存指针:描述进程内存资源使用的详细情况;
- 进程运行过程中需要消耗一些系统资源,内存是一种重要资源;
- 内存必须要先分配才能使用,不能随意使用;
- 内存指针就是描述某个进程都能使用哪些内存;
- 进程运行起来的时候需要指令和数据;
- 进程也需要知道,哪个内存地址存的是指令,哪个内存地址存的是数据;
- 进程创建之前需要在内存中加载指令和数据,再创建进程,开始执行;
文件描述符表:描述了进程所涉及的硬盘相关的资源;
- 进程也需要经常访问硬盘;
- 操作系统对于硬盘资源进行了抽象封装,按照文件的方式进行操作;
- 进程要操作文件,需要先打开文件;
- 打开文件之后,文件描述符表中会新增一个记录,用于记录文件的相关信息;
进程指令在 CPU 上的执行方式;
- 一个 CPU 可能有一个核心,也可能有多个核心;
- 同一时刻,同一个 CPU 核心只能执行一个指令;
- 实际中操作系统往往都是多任务操作系统,往往需要执行几十个甚至上百个进程,远远大于 CPU 核心数;为了将所有进程都运行起来,采用了分时复用的方式,让多个进程的指令轮流执行,也就是并发;只要进程的切换速度足够快,人无法感知到进程的切换过程,看起来就是同时执行的;但是如果进程的数量过于多,就会出现卡顿的现象;
- 如果 CPU 有多个核心,就可以同时执行多个进程的指令,是并行执行;
- 多个进程的指令在一个 CPU 核心上轮流执行,是并发执行;
- 并发执行和并行执行,统称为并发执行,并行和并发往往是同时存在的;
- 不同进程指令在 CPU 上执行的时间占比就是占用 CPU 资源的占比;
因此,进程的调度实际上是分时复用,并发执行的;下面继续介绍 PCB 中的核心属性:
进程状态:描述某个进程是否能够去 CPU 上执行:
- 如果进程是就绪状态,可以随时去 CPU 上执行;
- 如果进程是阻塞状态,表示目前不能去 CPU 上执行;
优先级:多个进程等待系统的调度,往往多个进程的优先级是不同的;
记账信息:统计不同进程在 CPU 上的执行时间;
- CPU 会根据记账信息,进一步调整进程的调度策略;
- 避免出现某一个进程的指令没有去 CPU 上执行,确保每一个进程的指令都能够获取 CPU 资源,指令都能够在 CPU 上执行;
上下文:是支撑进程调度的重要属性,保存了进程上一次执行完时寄存器的值;
- 保存上下文:把 CPU 的关键寄存器中的数据,保存到内存中(PCB的上下文属性中);
- 恢复上下文:把内存中关键寄存器中的数据,加载到 CPU 的对应寄存器中;
3. 进程的内存管理
不同的进程使用内存的不同区域,通常来说,进程之间的的内存时彼此独立,互不干扰的;
4. 进程间通信
进程间的通讯往往会借助一些公共空间,借助公共空间来交互数据;
Java 中往往会借助文件和网络进行进程间通讯;