引起死锁的主要是需要采用互斥访问方法的、不可被抢占的资源
定义:一种可供用户重复使用多次的资源
性质:
对资源的请求和释放利用系统调用实现【设备:request / release;文件:open / close;需要互斥访问的资源:用信号量的 wait / signal】。每次在进程提出资源请求后,系统执行时需要做出一系列的工作
计算机系统中大多数资源属于可重用资源
别称:临时性资源
定义:在进程运行期间由进程动态创建和消耗的
性质:
可消耗资源通常由生产者进程创建、由消费者进程消耗
定义:某进程在获得这类资源后,这类资源可以再被其他进程或系统抢占
因处理机和内存均属于可抢占资源,故此类资源不会引起死锁
定义:一旦系统把这类资源分配给某进程后,就不能将其强行收回,只能在进程用完后等待其自行释放
作用:描述系统死锁
资源分配图是一个有向图,由一组节点 N 和一组边 E 所组成的一个对偶 G=(N,E)
N:两个互斥的子集,一组进程节点 P={P1,P2,...,Pn}
,一组资源节点 R={R1,R2,...,Rn}
,N=P∪R
E:e∈E
e={Pi,Rj}
,资源请求边Pi—>Rj
,表示进程 Pi 请求一个单位的 Rj 资源e={Rj,Pi}
,资源分配边Rj—>Pi
,表示把一个单位的资源 Rj 分配给进程 Pi前者不会发送死锁,后者会发生死锁
① ② ③
④:进入不安全区 D,若两个进程继续向前推进,可能发送死锁
若一组进程中的每个进程都在等待仅由该组进程中的其他进程才能引发的事件发生,那么该组进程是死锁的
死锁:各进程相互等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象
饥饿:由于长期得不到想要的资源,某进程无法向前推进的现象
死循环:某进程执行过程中一直跳不出某个循环的现象,有时是因为程序逻辑 bug 导致的,有时是程序员故意设计的
共同点 |
区别 |
|
死锁 |
都是进程无法顺利向前推进的现象(故意设计的死循环除外) |
死锁一定是“循环等待对方手里的资源”导致的,故若有死锁现象,则至少有两个或两个以上的进程同时发生死锁。此外,发生死锁的进程一定处于阻塞态 |
饥饿 |
可能只有一个进程发生饥饿。发生饥饿的进程可能是阻塞态(长期得不到需要的 I/O 设备),也可能是就绪态(长期得不到处理机) |
|
死循环 |
可能只有一个进程发生死循环。死循环的进程可以上处理机运行(可以是运行态),只不过无法像期待的那样顺利推进。死锁和饥饿问题是由于操作系统分配资源的策略不合理导致的,而死循环是由代码逻辑的错误导致的。死锁和饥饿是管理者(操作系统)的问题,死循环是被管理者的问题 |
产生死锁必须同时具备下列 4 个必要条件,只要其中任意一个条件不成立,死锁就不会发生
进程对所分配到的资源进行排他性使用,即在一段时间内,某资源只能被一个进程占用。若此时还有其他进程请求该资源,则请求进程只能等待,直至占有该资源的进程用毕释放
进程已占有至少一个资源,但又提出新的资源请求,而该被请求的资源已被其他进程占有,此时请求进程被阻塞,同时其对自己已占有的资源保持不放
进程已获得的资源在未使用完之前不能被抢占,只能在进程使用完时由其自己释放
在发生死锁时,必须存在一个“进程 - 资源”循环链,即进程集合{P0,P1,P2,...,Pn}
中的 P0 正在等待已被 P1 占用的资源,P1 正在等待已被 P2 占用的资源,……,Pn 正在等待已被 P0 占用的资源
从原理上说,处理死锁有 3 种主要策略:
预防死锁:一种较简单和直观的事先预防方法,通过设置某些限制条件,去破坏产生死锁的 4 个必要条件中的一个或几个预防死锁,一种较易实现的方法,已被广泛使用
避免死锁:事先预防方法,不需要通过事先采取各种限制措施破坏产生死锁的 4 个必要条件,在资源的动态分配过程中,用某种方法防止系统进入不安全状态
检测死锁:无须事先采取任何限制性措施,允许进程在运行过程中发生死锁。可通过检测机构及时地检测出死锁的发生,然后采取适当措施把进程从死锁中解脱出来
解除死锁:当检测到系统中已发生死锁时采取相应措施,将进程从死锁状态中解脱出来。常采用的措施是撤销一些进程,回收其资源,将回收的资源分配给已处于阻塞状态的进程,使这些进程能够继续运行
互斥条件是非共享设备必须具备的条件,不能改变,应该加以保证
必须保证做到:当一个进程在请求资源时,不能持有不可抢占资源
内容:
优点:简单、易行、安全
缺点:
内容:
规定允许一个进程只获得运行初期所需的资源后,便开始运行。进程运行过程中再逐步释放已分配给自己的、且已用毕的全部资源
协议:规定当一个已经保持了某些不可抢占资源的进程提出新的资源请求而不能得到满足时,其必须释放已经保持的所有资源,待以后需要时再重新申请【进程已占有的资源会被暂时释放,或者说被抢占,从而破坏“不可抢占”条件】
缺点:实现复杂,需付出很大代价,延长进程的周转时间,增加系统开销,降低系统吞吐量
对系统的所有资源类型进行线性排序,并赋予其不同的序号
预防协议:规定每个进程必须按序号递增的顺序请求资源,若需要多个同类资源单元,则必须一起请求。加入某进程已请求到一些序号较高的资源,后来又想申请序号较低的资源,则必须先释放所有具有相同的和更高序号的资源,然后才能申请序号低的资源。事实上,总有一个进程会占据较高序号的资源,此后其继续申请的资源必然是空闲的,因而进程可以一直向前推进
重点:如何规定每种资源的序号,通常根据大多数进行需要资源的先后顺序确定资源的序号
优点:资源利用率和系统吞吐量明显改善
存在的问题:
在资源动态分配过程中,防止系统进入不安全状态,以避免发生死锁
此方法所施加的限制条件较弱,可能会获得较好的系统性能
避免死锁的实质:使系统在进行资源分配时不进入不安全状态
方法:允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次资源分配的安全性。若此次分配不会导致系统进入不安全状态,则可将资源分配给进程,否则,令进程等待
当系统处于安全状态时可避免发生死锁,而当系统处于不安全状态时,可能会进入死锁状态
安全状态:系统能按某种进程推进顺序(P1,P2...,Pn)
,为每个进程 Pi 分配其所需的资源,直至满足每个进程对资源的最大需求,进而使每个进程都可顺利完成的一种系统状态
安全序列:进程推进顺序(P1,P2,...,Pn)
不安全状态:若系统无法找到一个安全序列,则称系统处于不安全状态
并非所有不安全状态都会转为死锁状态,但当系统进入不安全状态后,就可能进入死锁状态
只要系统处于安全状态,其就不会进入死锁状态
若不按照安全序列分配资源,则系统可能会由安全状态进入不安全状态
分析:
(P2,P1,P3)
(p2,p1,p3)
为实现银行家算法,每个新进程在进入系统时,都必须申明在运行过程中可能需要每种资源类型的最大单元数目,该数目不应超过系统所拥有的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源可分配给该进程。若有,则进一步计算在将这些资源分配给该进程后,系统是否会处于不安全状态。若不会,则将资源分配给该进程,否则让该进程等待
Available[j]=K
,表示系统中现有 Rj 类资源 K 个Max[i,j]=K
,表示进程 i 需要 Rj 类资源的最大数目为 KAllocation[i,j]=K
,表示进程 i 当前已分得 Rj 类资源的数目为 KNeed[i,j]=K
,表示进程 i 还需要 Rj 类资源 K 个方能完成其任务Need[i,j]=Max[i,j]-Allocation[i,j]
设 Requesti 是进程 Pi 的请求向量,若Requesti[j]=K
表示进程 Pi 需要 K 个 Rj 类型的资源。当 Pi 发出资源请求后,系统会按下列步骤进行检查
Requesti[j] ≤ Need[i,j]
,则转向步骤 2;否则认为出错,因为其所需的资源数已超过它所宣布的最大值Requesti[j] ≤ Available[j]
,则转向步骤 3;否则表示尚无足够资源,Pi 须等待Available[j] = Available[j] - Requesti[j];
Allocation[i,j] = Allocation[i,j] + Requesti[j];
Need[i,j] = Need[i,j] - Requesti[j];
Work = Available
Finish[j] = FALSE
;当有足够的资源可分配给进程时,在令Finish[j] = TRUE
Finish[j] = FALSE
;②Need[i,j] ≤ Work[j]
。若能找到,则执行步骤 3;否则,执行步骤 4Work[j] = Work[j] + Allocation[i,j];
Finish[i] = TRUE;
go to step 2;
Finish[i] = TRUE
,则表示系统处于安全状态;否则,系统处于不安全状态死锁检测算法:用于检测系统状态,以确定系统中是否发生了死锁
为了能对系统中是否已发生死锁进行检测,在系统中必须:①保存有关资源的请求和分配信息 ②嵌入一种算法,使其能够利用这些信息检测系统是否已进入死锁状态
若某时刻系统的资源分配图是不可完全简化的,那么此时系统死锁
可利用资源向量 Available:表示 m 类资源中每类资源的可用数目
把不占用资源的进程(向量Allocation=0
)记入 L 表,即Li∪ L
从进程集合中找到一个Requesti ≤ Work
的进程,做如下处理:
① 将其资源分配图简化,释放出资源,增加工作向量,即令Work = Work + Allocation
② 将其记入 L 表
若不能把所有进程都记入 L 表,则表明系统状态 S 的资源分配图是不可完全简化的,故此系统将发生死锁
死锁解除算法:当确定系统中发生了死锁时,利用该算法将系统从死锁状态中解脱出来
解除死锁的方法:
地位:一种最简单的方法
缺点:付出的代价可能会很大,因为有些进程可能已经运行了很长时间并已接近结束……
描述:按照某些顺序逐个终止死锁进程,直至有足够的资源来打破循环等待,把系统从死锁状态中解脱出来
缺点:所付出的代价可能很大,因为每终止一个进程,都需要用死锁检测算法确定系统死锁是否已被解除,若未被解除,则须再终止另一个进程
选择策略的主要依据:为解除死锁而付出的代价最小
选择被终止死锁进程时的考虑因素:
PS:多重遍历,循环次数为 n!
PS:找到局部最优,再从局部最优继续找局部最优,n 个进程最多只需要 n 次寻找
代价: