0.操作系统——进程的操控者
操作系统本质上是人机之间交互的接口,人通过操作系统(比如命令行、窗口、菜单)去操控计算机硬件;同时也是应用软件与硬件之间的接口(换而言之可以控制程序的运行)
操作系统的五大作用:进程管理、存储管理、文件管理、作业管理、设备管理
上图就是典型的计算机结构:硬件层——>操作系统——>其他系统软件——>应用软件
1.进程与线程的基本概念
进程,是程序在一个数据集合上运行的具体过程,是一个动态的概念,是系统进行资源分配和调度的基本单位,是程序的一次执行过程(创建就产生,撤销就消亡)
进程有两个基本属性:
1.可拥有资源的独立单位
2.可独立调度和分配资源的基本单位
由程序块(进程执行的程序)、进程控制块(PCB,进程执行的相关记录)和数据块(执行所需要的数据)组成
要特别注意PCB:是进程存在的唯一标志,包括进程的标识符、状态、位置信息、控制信息、队列指针(用来链接同一状态的进程)、优先级、现场保护区等
PCB的组织方式有多种,如下图为索引方式,即我们建立了一个索引表来查找对应的PCB
如果是顺序方式,逻辑顺序和物理顺序是一致的,即逻辑上相邻物理位置上也相邻,换而言之我们不需要索引表,指针和PCB直接对应,逐个往下查就可以了
如果是链接方式,类似于链表,前面的节点有一个线索指向后面一个节点(索引方式是单独记录的,不一定是指向下一个),即我们不需要索引表,只要在PCB中设置好下一个PCB是谁就可以了
还有不常用的hash方式,根据hash函数计算存在哪里
程序,是一个静态的概念,操作系统用不用,程序都客观存在
线程:是进程内部的子单位(比如支持多线程的操作系统中,一个进程可创建多个线程),可以被独立调度,但不能分配资源;它的资源也不是独立被分配的,可能会与其他线程共享(但程序计数器、寄存器、栈空间不可共享)
2.进程的状态
动态的进程有不同的状态变迁,模型有很多种,我们来看三态模型和五态模型
三态模型:
是进程状态的基础,将整个进程运行状态分为:运行、阻塞、就绪
该模型会把cpu(核心资源)和非cpu资源做分类,根据资源占据的情况来划分进程的状态,举例:
- 运行态:cpu资源就绪,非cpu资源也就绪了,进程就会被cpu调度从而进入运行态;一个进程不会长时间占用cpu资源,cpu资源会被划分为多个时间片,某一个进程自己的时间片用完了还未分到新的资源,就会进入就绪态去排队等待下一个时间片的到来
- 就绪态:cpu资源就绪,非cpu资源未就绪,等待非核心资源的分配
- 阻塞态:两个资源都不足,等待资源
如果考虑挂起,就会有五态模型:
内存资源不足的时候,将某个进程挂起从内存移动到磁盘里变为静止xx的状态,后面我们再运行
4.信号量与PV操作
由于在一个计算机中进程有很多很多,因此进程与进程之间就会有不同的关系,主要是互斥与同步
- 互斥:进程之间相互抵制,有些临界资源同一时间只能让少数进程来用,但是需要用它的进程很多,就会出现互斥现象。这种情况又叫做间接制约关系
- 同步:进程之间的依赖关系,进程A可能会依赖于进程B的一些结果,但他们运行的速度有差异,所以就会出现进程A等待进程B或者进程B等待进程A的情况。这种情况叫直接制约关系
一些背景知识:
- 临界资源:进程需要以互斥方式对其进行共享操作的资源,类似于缓存区,一次只能有一个进程使用
- 临界区:每个进程中访问临界资源的那段代码
- 信号量(S):特殊的变量,一种全局变量,可以拿来记录相应的资源数量
- P操作:信号量减1(可以理解为占据/锁定/申请1个资源),如果信号量小于0就说明没有资源了,就把当前进程放入阻塞队列去等资源(S负的越多,等待资源的进程越多);如果没小于0就继续
- V操作:信号量加1(可以理解为释放资源的过程),如果信号量小于等于0,说明现在的阻塞队列里是有进程在排队的,就需要去通知下他们有资源可以用了,就会进入就绪状态;如果没有小于等于0就继续
5.前驱图与PV操作
前趋图包含了节点和键线,分别代表进程、进程与进程间的依赖关系,体现的是进程之间的直接制约关系(间接制约是资源制约)
如下图,表示了A进程是B进程的前驱,B进程是A进程的后继(后继活动开始前前驱必须要完成,用(A,B)表示)
用PV理解前趋图,有如下前趋图:
在D进程开始之前,需要检查ABC是不是完成了,用P操作来看,就是D去请求一个资源,用V操作来看,就是ABC去释放一个资源,且三个信号量的初始值都是0;可以看出,前趋图中的箭头流入就是一个P操作,流出就是一个V操作,每一个键线代表一个信号量
表示为:{ (A,D), (B,D), (C,D), (D,E) }
6.死锁
由于进程管理是操作系统的核心,如果设计不当就可能会出现死锁问题——即一个进程在等待一个永远不可能发生的事情,比如一个永远给不了它的资源
死锁要同时满足的四大条件才能成立:
- 互斥:某个资源为临界资源,其他进程拿不到,就会死锁
- 环路等待:比如A等B的cpu资源,B等A的内存资源,他们互相等待都不执行,就会死锁
- 不剥夺:进程不会剥夺其他进程正在用的资源,如果自己需要的资源其他进程在用,就会死锁
- 保持和等待:进程会保持当前的资源,会等待其他进程释放资源,如果他等不到就会死锁
打破死锁:
- 有序资源分配法:先给A分配组,再给B分配,不存在用了对方资源的情况
- 银行家算法
7.页式存储
操作系统有的时候会将外存中的一些文件调用到内存中给cpu使用,如果这个文件非常的大,即使一次只需要调用一点点,也很难遇到内存中有这么多连续的空间给你放置;所以我们需要把完整的内容切割之后才存储
最常用的就是分页存储(页式存储),把我们需要存的程序和与之对应的内存划分成相同大小的区域,分别称为页和块,以页为单位存入内存空间,对应页存的内存称为块
如下图,用户的文件被分为n页,并生成一个页表来记录页与块的映射(或:页号 与 块号/页帧号 的映射),其本质是逻辑地址和物理地址的映射
逻辑地址和物理地址的页内地址都是一样的(即低位是一样的),就好比一本书,你把它拆散了重新订起来,需要重新编页,但是每一页的内容是不变的,原来的页码和重新编写的页码就好比页号和页帧号的对应关系,业内地址就好比你在这本书的哪个位置可以找到某个字,后者是不变的(比如8KB的页大小,就需要13位的页内地址来表示,即2^13)
页式存储的优缺点:
- 优点:利用率高,碎片小,分配与管理简单
- 缺点:因为比较零碎,可能需要多次查询,增加了系统开销;可能产生抖动现象(如果分配给进程的存储块数量小于进程所需要的最小值,进程的运行将很频繁地产生缺页中断,这种频率非常高的页面置换现象称为抖动)
页表的其他属性:
访问位会定时被清理,时间是人为约定的
8.段式存储
分页存储的最大确定就是可能会把一串逻辑的代码切分到不同的页,因此就有了段式存储
段式存储:按用户作业中的自然段来划分逻辑空间,然后存入内存,段的长度可以不一样;
如下图,用户的作业被分为多个段,并生成一个段表来记录每一个段的 段号 与其 段长 与 基址 的映射。
与分页类似,我们也有:逻辑段地址 = 段号对应的基址 + 端内偏移量(必须>=段长)
比如上图上段号为2的逻辑地址,可以表示为 (2, 135K)、(2, 140K),只要偏移量大于段长即可,如果小于的话,逻辑地址到物理地址转换的时候地址会越界
段式存储的优缺点:
- 优点:多道程序共享内存(比如一个很常用的函数),各段程序修改互不影响
- 缺点:内存利用率低,内存碎片浪费大
9.段页式存储
即以上两种存储方法的结合,是段式和页式的综合体——先分段(大小不同),再分页(大小相同)
找到程序的过程,大概可以概括为:先查段表、再查页表,它的逻辑地址即为:段号 + 页号 + 页内地址, 的形式
段页式存储的优缺点:
- 优点:空间浪费小,存储共享容易、存储保护容易、能动态连接
- 缺点:由于管理软件的增加,复杂性和开销也随之增加,需要的硬件以及占用的内容也有所增加,使得执行的速度大大下降