目录
前言:
本文前置文章:
死锁问题
死锁是系统中的恶性小概率事件,指两个或多个进程无限期地等待永远不会发生的事件,系统处在停滞状态
死锁的定义
死锁指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象
若无外力作用,它们都将无法向前推进
产生死锁的原因
产生死锁的原因有两个:“竞争临界资源”、“进程推进顺序不当”
- 竞争临界资源:当系统中供多个进程共享的临界资源(打印机、公用队列等)的数目不能满足诸进程时,会引起诸进程对临界资源的竞争而产生死锁
- 进程推进顺序不当:进程在运行过程中,请求和释放资源的顺序不当
产生死锁的必要条件
产生死锁的4个必要条件:
- 互斥条件:每一资源或者被分配给一个进程、或者空闲
- 占有并请求条件:已分配到了一些资源的进程可以申请新的资源
- 不可剥夺条件:已分配给某进程的资源不可被剥夺,只能由占有它的进程使用完后主动释放
- 循环等待条件:系统必然存在一条由两个或两个以上进程组成的循环链,链中的每一个进程都在等待相邻进程所占用的资源
注意:“只要有一条上述条件没有满足,那么就不会发生死锁”
死锁的预防
死锁的预防就是通过破坏产生死锁的必要条件之一,使系统不会产生死锁
这种方法在系统运行之前就采取措施
常见的有两种方法:“静态资源分配法”、“有序资源使用法”
- 静态资源分配法:系统规定每一个进程在开始运行前,都必须一次性地申请其在整个运行过程所需的全部资源。此时若系统有足够的资源就全部给它,若没有全部资源则一个资源不给它
- 有序资源使用法:系统中的所有资源按类都被赋予了一个唯一的编号,每个进程只能按编号的“升序”申请资源(对同一个资源来说,它一旦申请了一个编号为i的资源,就不允许再申请比编号比i小的资源了)
死锁的避免
死锁的避免就是系统运行过程中采取动态的资源分配策略,保证系统不进入可能导致系统陷入死锁状态的所谓不安全状态,从而避免死锁的发生
资源利用率比死锁的预防高
安全状态
若在某一时刻,系统能够某种进程顺序,如{P1,P2,....,Pn}为每个进程分配其所需的资源,直至最大需求,使所有的进程都可以顺利完成,则称此时系统的状态为安全状态
安全序列的实质是:序列中的每一个进程P到运行完成尚需的资源量不超过系统当前剩余的资源量与所有在序列中排在它前面的进程当前所占有的资源量之和
若在某时刻,系统中不存在一个安全序列,则称系统处于不安全状态
注意:
- 系统在某一时刻的安全序列可能不唯一,但这不影响对系统安全性的判断
- 安全态是非死锁状态,而不安全状态并不一定是死锁状态状
“安全状态”、“不安全状态”、“死锁状态”三者的关系如下图所示:
银行家算法【重点理解】
银行家算法的实质就是:“设法保证系统动态分配资源后不进入不安全状态,以避免可能产生死锁”
即:“进程提出资源请求且系统的资源能够满足该请求时,系统将判断满足此次资源请求后系统状态是否安全,如果判断结果为安全,则给该进程分配资源,否则不分配资源”
下面介绍银行家算法中所用的主要数据结构:
- 可用资源向量available:记录系统中各类资源的当前可用数目
- 最大需求矩阵max:记录每个进程对各类资源的最大需求量
- 分配矩阵allocation:记录每个进程对各类资源的当前占有量
- 需求矩阵need:记录每个进程对各类资源尚需要的数目,它等于max - allocation
- 请求向量request:记录某个进程对各类资源的申请量
银行家算法的描述如下:(设进程P向系统提出request资源请求)
- 若request > need,则进程P出错(申请的资源量大于所需资源量,必然出错)
- 若reques > available,则进程P堵塞(申请资源量大于可用资源量,只能堵塞进程)
- 系统试着把资源分配给进程P,并对相应数据结构作如下修改:
- available - request
- allocation + request
- need - request
- 系统执行安全性检测子算法,判断分配后系统状态是否安全
- 若第4步返回逻辑真值,则安全,完成本次分配
- 若第4不返回逻辑假值,则不安全,撤销本次分配
安全性检测子算法的描述:
这个子算法实质就是寻找安全序列的过程,如果找到就返回逻辑真值,找不到就返回逻辑假值
子算法的数据结构与银行家算法的相同,另外增加了两个向量:
- 工作向量work:记录系统中各类资源的当前可用数目
- 标志向量finish:记录进程是否可完成(是否可加入安全序列)
安全性检测子算法的执行过程:
- 初始化:work = available,finish = false
- 若按进程编号的顺序找到了一个可加入安全序列的进程,即满足条件:finish = false,且need < work的进程P,则假设该进程不久后将完成任务归还资源,于是置work = work+allocation 和 finish = true,然后重复执行这一步
- 若所有进程的finish为真,则返回逻辑真值
- 若有个进程finish为假,则返回逻辑假值
下面是一道例题:
①:
判断t0时刻是否安全,需要用到安全性检测子算法
首先work = available = (1,1,2),之后搜寻满足条件的need,P1不能满足,P2满足,之后置work = work + allocation2 = (6,2,3)
再一次搜寻满足条件的need,P1此时满足,之后置work = work + allocation = (7,2,3)
如此重复,直到将所有的P进程加入到序列中,此时t0时刻是安全的,如下图所示:
②:
P2发送请求request(1,0,1),系统按照银行家算法进行检查:
- request(1,0,1) < work(1,1,2) 符合条件
- request(1,0,1) < need(1,0,2) 符合条件
- 系统假设可为P2分配资源,同时修改available、allocation、need,如下图所示:
- 最后利用安全性检测子算法检查系统是否安全
由此可知,系统可以将P2申请的资源分配给它
③:
P1请求request(1,0,1),系统按银行家算法进行检查:
- request(1,0,1) < need(2,2,2) 符合条件
- request(1,0,1) > available(0,1,1) 不符合条件
- 因此P1的请求被驳回
④:
P3请求request(0,0,1),系统按银行家算法进行检查:
- request(0,0,1) < need(1,0,3) 符合条件
- request(0,0,1) < available(0,1,1) 符合条件
- 系统假定可以为P3分配资源,修改available、allocation、need2
- 最后用安全性检测子算法检查此时系统是否安全,因可用资源available(0,1,0)不能满足任何进程,因此这是一个不安全状态,所以P3的请求被驳回
死锁的检测
死锁的检测适用于那些对死锁的产生不采取任何预防或避免的对策
其功能由两部分实现:“死锁检测程序”和“死锁解除程序”
- 死锁检测程序:确定系统中是否存在死锁,并试图找出陷入死锁的进程和资源
- 死锁的解除:死锁的解除有两种方法:“撤销进程法”和“挂起进程法”
- 撤销进程法:系统计算死锁进程的撤销代价,然后依次撤销代价最小的进程,逐个撤销死锁进程,回收资源给其它进程,直至死锁不存在
- 挂起进程法:挂起一些死锁进程,暂时剥夺它们占有的资源,以解除死锁,当系统中可利用的资源增多时,再激活被挂起的进程
鸵鸟算法
系统不对死锁做出任何回答,反而提供给用户查看与杀死指定进程的命令
当出现死锁时,交给用户处理
处理机调度
处理机管理需要解决以下三个主要问题:
- 确定处理机调度算法
- 确定处理机调度时机
- 处理机调度过程
三级调度概念
处理机调度常分为:“高级调度”、“中级调度”、“低级调度”(长程调度、中程调度、短程调度)三种
- 高级调度:又称作业调度
- 中级调度:又称内存调度
- 低级调度:又称进程调度
分时系统通常只有后两种调度,早期的批处理系统支持三级调度,如下图所示:
调度算法
在系统中,处于就绪状态的多个进程竞争使用一台处理机,所以当处理机空闲时,系统需要从多个就绪进程中挑选一个使其运行,该选用哪一个,就用到了调度算法
常见的调度算法有:“先来先服务调度算法”、“短作业优先调度算法”、“最高响应比优先调度算法”、“优先级调度算法”、“时间片轮转调度算法”、“多级反馈调度算法”
先来先服务调度算法
算法按照进程进入就绪队列的先后顺序选择可以占用处理机的进程
优点:实现简单
缺点:后来的进程等待CPU时间长
短作业优先调度算法
算法总是选取估计运行时间最短的作业投入运行
优点:系统吞吐量大、实现简单
缺点:长作业等待时间过长
最高响应比优先调度算法
算法总是选取响应比最高的作业投入运行
优点:改善了批处理系统调度性能
缺点:每次调度时需要计算各道作业的响应比,导致一定时间开销
优先级调度算法
算法总是选择具有最高优先级的进程首先使用处理机
下面看一道例题:
①:
先来先服务调度算法按照进入就绪队列的顺序,题目中从上到下排列,因此顺序也是从上到下排列
故:P1 -> P2 -> P3 -> P4 -> P5
静态优先级调度算法按照优先数的大小,降序排列
故:P4 -> P1 -> P3 -> P5 -> P2
(这里先P1后P3的原因是:当两个进程优先级相同时,则按照先来先服务策略,谁先进入处理机,先调度谁)
②:
我们可以列表表示所有进程的等待时间
例如,在先来先服务算法中:
P1是第一个执行的进程,故等待时间为0s
P2是第二个执行的进程,故等待时间为P1的处理机时间为10s
P3是第三个执行的进程,故等待时间为P1+P2的处理时间为10+1 = 11s
P4是第四个执行的进程,故等待时间为P1+P2+P3的处理时间为10+1+2=13s
P5是第五个执行的进程,故等待时间为P1+P2+P3+P4的处理时间为10+1+2+1=14s
故先来先服务法中,平均等待时间为 = (0+10+11+13+14) / 5 = 9.6
故静态优先级法中,平均等待时间为 = (1+18+11+0+13) / 5 = 8.6
时间片轮转调度算法
系统把所有的就绪进程按先来先服务的原则排成一个队列,且规定一个时间片作为进程每次使用处理机的最长实践单位,按时间片把处理机轮流分配给当前位于就绪队列队首的进程使用
多级反馈调度算法
该算法综合了先来先服务法、优先级法、时间片轮转法等思想和优点
总体调度性能优越,适用于各种类型的作业,但实际开销较大
算法思想是:“系统按进程优先级设置多级就绪进程队列,每一级就绪队列对应不同的时间片。从第一级队列到最后一级队列,优先级越来越低,时间片越来越大。当一个新进程进入内存后,首先被放到第一级队列的队尾。系统调度时,总是从第一级队列开始,当第一级队列为空时,才调度第二级队列,如此往复,直到最后一级队列”
调度时机
当发生以下几种情况时,现行进程都要放弃处理机的使用:
- 在分时系统中,现行进程的时间片用完了
- 发生了外部中断
- 进程因等待某时间或资源而阻塞
- 现行进程运行结束或出现异常情况
调度过程
系统处理完中断事件后,如果需要进行进程切换,则转到处理机调度程序选择下一个运行进程
处理机调度需要经历三个步骤:“保存下降进程现场”、“选择将要运行的进程”、“恢复上升进程的现场”
保存下降进程现场
中断响应时,硬件中断装置把中断执行的进程--“下降”进程的中断向量压入系统堆栈区
简单来说,把系统当前运行的状态保存下来,方便下一次使用处理机时,继续处理未完成的任务
选择将要运行的进程
按照处理机调度算法从就绪队列中选择一个进程,准备让它运行
恢复进程现场
恢复之前进程中断处理机时的状态,继续执行未执行完任务
线程的概念
线程的定义
线程是进程中可独立执行的子任务,是系统独立调度和分派的基本单位
一个进程中至少有一个线程
线程继承所属进程的一切资源,它自己只拥有运行所需的很少的一点资源
线程与进程的比较
线程具有传统进程所具有的许多特征,故又称为轻型进程,而把传统进程称为重型进程
下面从四个方面比较线程与进程
拥有资源
进程是拥有资源的一个独立单位,线程几乎不拥有系统资源
调度
进程是拥有资源的基本单位,线程是调度与分派的基本单位
并发性
进程之间可以并发执行,线程之间也可以并发执行
系统开销
操作系统创建/切换进程的开销远大于创建/切换线程的开销
线程、进程、作业、程序之间的关联
- 作业:批处理系统中用户向计算机提交任务的任务实体
- 进程:分时系统中用户向计算机提交任务的任务实体
作业、进程、线程都是动态的,只有程序是静态的