狭义定义:进程是正在运行的程序的实例。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。也就是说进程是系统进行资源分配的基本单位。
一个跑起来的程序就叫做进程,每个进程想要执行都需要消耗一定的系统资源(硬件资源)。我们可以打开任务管理器来查看后台运行的进程和占用的资源。
那么进程在系统中是如何管理的呢,我们从两个角度考虑:
1.描述:使用类/结构体,把被管理的一个对象各个属性都表示出来。
2.组织:使用数据结构,把这些表示出来的对象串起来(为了后续的增删改查)。
系统中有一个专门的结构体(操作系统内核使用的是C/C++写的)描述进程的属性,这个结构体称为“进程控制块” PCB,一个进程可以使用一个或多个PCB来表示。
系统中会使用类似于双向链表这样的数据结构来组织多个PCB。
创建新的进程就是创建PCB并把PCB插入到链表中。
销毁进程就是把PCB从链表中删除并释放。
展示进程列表就相当于遍历链表的每个节点。
PCB中引入了一些属性,用来支持操作系统实现进程调度的效果。
(1)进程的状态:①就绪状态有两种情况一是指进程正在CPU上执行,二是进程没有在CPU上执行,但随时可以去CPU上执行。②阻塞状态:某个进程某种执行条件不具备,就导致进程暂时无法参与CPU的调度执行。
(2)进程的优先级:操作系统在调度多个进程时并不会“一视同仁”,有些进程优先级更高,就优先调度。
(3)进程的上下文:进程从CPU离开之前,需要”保存现场“,把当前CPU中各种寄存器的状态都记录到内存中,等下次进程回到CPU上执行的时候,就可以把寄存器的值恢复回去,进程就会沿着上次执行到的位置继续向后执行。
(4)进程的记账信息:通过优先级机制,对不同的进程分配了不同权重的资源。记账信息,会记录当前进程持有CPU的情况(在CPU执行多久了)就可以作为操作系统调度进程的参考依据。
虚拟地址空间
早期的操作系统,程序运行时分配的内存就是”物理内存“,操作系统要给进程提供稳定的运行环境,就引入了”虚拟地址空间“的概念,不是直接分配物理内存,而是分配虚拟的内存空间。
这里的A和B看到的内存都是虚拟内存,比如A操作某个内存中的数据,就需要把操作的虚拟内存地址告诉系统,系统再把操作的虚拟地址翻译成物理地址(有一个类似于hash表这样的映射结构,称为”页表“)。如过给的虚拟地址是一个非法的,比如一个越界访问。系统就能及时发现,就不会波及其他进程。