Skip to content

Commit 8437c0f

Browse files
committed
Merge branch 'main' of https://github.com/zhengjianda/JavaGuide into zhengjianda-main
2 parents 8213549 + 9e04950 commit 8437c0f

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed
Loading

docs/cs-basics/operating-system/operating-system-basic-questions-01.md

+87
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,93 @@ tag:
153153

154154
注意,只有四个条件同时成立时,死锁才会出现。
155155

156+
### 2.8 解决死锁的方法
157+
158+
#### 那么解决死锁的方法是什么呢?
159+
160+
解决死锁的方法可以从多个角度去分析,一般的情况下,有**预防,避免,检测和解除四种**
161+
162+
- **预防** 是采用某种策略,**限制并发进程对资源的请求**,从而使得死锁的必要条件在系统执行的任何时间上都不满足。
163+
164+
- **避免**则是系统在分配资源时,根据资源的使用情况**提前做出预测**,从而**避免死锁的发生**
165+
166+
- **检测**是指系统设有**专门的机构**,当死锁发生时,该机构能够检测死锁的发生,并精确地确定与死锁有关的进程和资源。
167+
- **解除** 是与检测相配套的一种措施,用于**将进程从死锁状态下解脱出来**
168+
169+
#### 死锁的预防
170+
171+
死锁四大必要条件上面都已经列出来了,很显然,`只要破坏四个必要条件中的任何一个就能够预防死锁的发生`
172+
173+
破坏第一个条件 **互斥条件**:使得资源是可以同时访问的,这是种简单的方法,磁盘就可以用这种方法管理,但是我们要知道,有很多资源**往往是不能同时访问的**,所以这种做法在大多数的场合是行不通的。
174+
175+
破坏第三个条件**非抢占**:也就是说可以采用**剥夺式**调度算法,但剥夺调度方法目前一般仅适用于**主存资源****处理器资源**的分配,并不适用于所以的资源,会导致**资源利用率下降**
176+
177+
所以一般比较实用的**预防死锁的方法**,是通过考虑破坏第二个条件和第四个条件。
178+
179+
- **静态分配策略**:所谓静态分配策略,就是指一个进程必须在执行前就申请到**它所需要的全部资源**,并且知道它所要的资源都得到满足之后才开始执行。这种做法破坏了死锁产生的第二个条件**占有并等待**,进程要么占有所有的资源然后开始执行,要么不占有资源,不会出现占有一些资源等待一些资源的情况。
180+
静态分配策略逻辑简单,实现也很容易,但这种策略**严重地降低了资源利用率**,因为在每个进程所占有的资源中,有些资源是在比较靠后的执行时间里采用的,甚至有些资源是在**额外的情况**下才是用的,这样就可能造成了一个进程占有了一些**几乎不用的资源而使其他需要该资源的进程产生等待**的情况。
181+
182+
- **层次分配策略**:层次分配策略破坏了产生死锁的第四个条件(**循环等待**)。在层次分配策略下,所有的资源被分成了多个层次,一个进程得到某一次的一个资源后,**它只能再申请较高一层的资源**;当一个进程要释放某层的一个资源时,必须先释放所占用的**较高层的资源**,按这种策略,是不可能出现**循环等待链的**,因为那样的话,就出现了已经申请了较高层的资源,反而去申请了较低层的资源,不符合**层次分配策略**,证明略。
183+
184+
#### 死锁的避免
185+
186+
上面提到的**破坏**死锁产生的四个必要条件之一就可以成功**预防系统发生死锁**,但是会导致**低效的进程运行****资源使用率**。而死锁的避免相反,它的角度是允许系统中**同时存在四个必要条件**,只要掌握并发进程中与每个进程有关的资源动态申请情况,做出**明智和合理的选择**,仍然可以避免死锁,因为四大条件仅仅是产生死锁的必要条件。
187+
188+
我们将系统的状态分为**安全状态****不安全状态**,每当在未申请者分配资源前先测试系统状态,若把系统资源分配给申请者会产生死锁,则拒绝分配,否则接受申请,并为它分配资源。
189+
190+
`安全状态`:如果操作系统能够保证**所有的进程在有限的时间内得到需要的全部资源**,则称系统处于安全状态,否则说系统是不安全的。很显然,`系统处于安全状态则不会发生死锁,系统若处于不安全状态则可能发生死锁`
191+
192+
那么如何保证系统保持在安全状态呢?通过算法,其中最具有代表性的**避免死锁算法**就是Dijkstra的银行家算法,银行家算法用一句话表达就是,“当一个进程申请使用资源的时候,**银行家算法**通过先**试探**分配给该进程资源,然后通过**安全性算法**判断分配后系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待,若能够进入到安全的状态,则就**真的分配资源给该进程**”。
193+
194+
银行家算法详情可见[(41条消息) 一句话+一张图说清楚——银行家算法_土豆洋芋山药蛋的博客-CSDN博客_银行家算法](https://blog.csdn.net/qq_33414271/article/details/80245715)
195+
196+
操作系统教程树中讲述的银行家算法也比较清晰,可以一看.
197+
198+
死锁的避免(银行家算法)改善解决了**资源使用率低的问题**,但是它要不断地检测每个进程对各类资源的占用和申请情况,以及做**安全性检查**,需要花费较多的时间。
199+
200+
#### 死锁的检测
201+
202+
对资源的分配加以限制可以**预防和避免**死锁的发生,但是都不利于各进程对系统资源的**充分共享**。解决死锁问题的另一条途径是**死锁检测和解除**(这里突然联想到了乐观锁和悲观锁,感觉死锁的检测和解除就像是**乐观锁**,分配资源时不去提前管会不会发生死锁了,等到真的死锁出现了再来解决嘛,而**死锁的预防和避免**更像是悲观锁,总是觉得死锁会出现,所以在分配资源的时候就很谨慎)。
203+
204+
这种方法对资源的分配不加以任何限制,也不采取死锁避免措施,但系统**定时地运行一个 “死锁检测”**的程序,判断系统内是否出现死锁,如果检测到系统发生了死锁,再采取措施去解除它。
205+
206+
##### 进程-资源分配图
207+
208+
操作系统中的每一刻时刻的**系统状态**都可以用**进程-资源分配图**来表示,进程-资源分配图是描述进程和资源申请及分配关系的一种有向图,可用于**检测系统是否处于死锁状态**
209+
210+
用一个方框表示每一个资源类,方框中的黑点表示该资源类中的各个资源,每个键进程用一个圆圈表示,用**有向边**来表示**进程申请资源和资源被分配的情况**。约定$P_{i} \rightarrow R_{j}$为请求边,表示线程$P_{i}$申请资源类$R_{j}$中的一个资源**得不到满足**而处于等待$R_{j}$类资源的状态,该有向边从进程开始指到方框的边缘,表示进程$P_{i}$申请$R_{j}$类中的一个资源。反之,$R_{j}\rightarrow P_{i}$为**分配边**,表示R的一个资源分配给了P。
211+
212+
图中2-21是**进程-资源分配图**的一个例子,其中公有三个资源类,每个进程的资源占有和申请情况已清楚地表示在图中。在这个例子中,由于存在**占有和等待资源的环路**,导致一组进程永远处于等待资源的状态,**发生了死锁**
213+
214+
<img src="https://github.com/zhengjianda/JavaGuide/blob/main/docs/cs-basics/operating-system/images/%E8%BF%9B%E7%A8%8B-%E8%B5%84%E6%BA%90%E5%88%86%E9%85%8D%E5%9B%BE.jpg" height="300"></img>
215+
216+
217+
进程-资源分配图中存在环路**并不一定是**发生了死锁。因为循环等待资源仅仅是死锁发生的必要条件,而不是充分条件。图2-22便是一个有环路而无死锁的例子。虽然进程P1和进程P3分别占用了一个资源R1和一个资源R2,并且因为等待另一个资源R2和另一个资源R1形成了环路,但进程P2和进程P4分别占有了一个资源R1和一个资源R2,它们申请的资源得到了满足,在有限的时间里会归还资源,于是进程P1或P3都能获得另一个所需的资源,环路自动解除,系统也就不存在死锁状态了。
218+
219+
##### 死锁检测步骤:
220+
221+
知道了死锁检测的原理,我们可以利用下列步骤编写一个**死锁检测**程序,检测系统是否产生了死锁。
222+
223+
1) 如果进程-资源分配图中无环路,则此时系统没有发生死锁
224+
2) 如果进程-资源分配图中有环路,且每个资源类仅有一个资源,则系统中已经发生了死锁。
225+
3) 如果进程-资源分配图中有环路,且涉及到的资源类有多个资源,此时系统未必会发生死锁。如果能在进程-资源分配图中找出一个**既不阻塞又非独立的进程**,该进程能够在有限的时间内归还占有的资源,也就是把边给消除掉了,重复此过程,直到能在有限的时间内**消除所有的边**,则不会发生死锁,否则会发生死锁。(消除边的过程类似于**拓扑排序**)
226+
227+
#### 死锁的解除
228+
229+
当死锁检测程序检测到**存在死锁发生时**,应设法让其解除,让系统从死锁状态中恢复过来,常用的解除死锁的方法有以下四种:
230+
231+
1. **立即结束所有进程的执行,重新启动操作系统**
232+
233+
这种方法简单,但以前所在的工作全部作废,损失很大。
234+
235+
2. **撤销涉及死锁的所有进程**,解除死锁后继续运行
236+
237+
这种方法能彻底打破**死锁的循环等待**条件,但将付出很大代价,例如有些进程可能已经计算了很长时间,由于被撤销而使产生的部分结果也被消除了,再重新执行时还要再次进行计算。
238+
239+
3. 逐个撤销涉及死锁的进程,回收其资源直至死锁解除。
240+
241+
4. 抢占资源:从涉及死锁的**一个或几个进程**中抢占资源,把夺得的资源再分配给涉及死锁的进程直至死锁解除。
242+
156243
## 三 操作系统内存管理基础
157244

158245
### 3.1 内存管理介绍

0 commit comments

Comments
 (0)