当前位置: 首页 > news >正文

计算机操作系统——死锁(详细解释和处理死锁)

系列文章目录

计算机操作系统-计算机系统中的死锁


文章目录

  • 系列文章目录
  • 前言
  • 一、资源问题:
    • 计算机系统当中的死锁:
  • 二、死锁的定义、必要条件和处理方法:
    • 1.死锁的定义:
    • 2.产生死锁的必要条件:
    • 3.处理死锁的方法:
  • 三、避免死锁:
    • 1.系统安全状态的定义:
    • 2.安全状态的例子:
    • 3.不安全状态的例子:
    • 4.利用银行家算法避免死锁:
    • 5.具体示例:
  • 总结


前言

   在第二章中,我们已经涉及到死锁的概念,例如系统中只有一个扫描仪R1和一台刻录机R2,有两个进程p1和p2,他们都准备将扫描的文档刻录在CD光盘上,进程1先请求扫描仪R1并获得成功,进程2先请求刻录机R2也获得成功,后来P1又请求CD刻录机,因它已被分配给了P2而阻塞,P2又请求扫描仪,也因被分配给了进程1而阻塞,此时两个进程都被阻塞,双方都希望对方能释放出自己所需要的资源,但他们谁都因不能获得自己所需的资源去继续运行,从而无法释放出自己占有的资源,并且一直处于这样的僵持状态而形成死锁,又如,在第二章的哲学家进餐问题中,如果每个哲学家因饥饿都拿起了他们左边的筷子,当每一个哲学家又试图去拿起他们右边的筷子时,将会因为无筷子可拿而无限期地等待,从而产生死锁问题。接下来我们将对死锁发生的原因,如何预防和避免死锁等问题作较详细的介绍。


一、资源问题:

  在系统中有许多不同类型的资源,其中可以引起死锁的主要是,需要采用互斥访问方法的、不可以被抢占的资源,即前面介绍的临界资源。系统中这类资源有很多,如打印机,数据文件,队列,信号量等。

可抢占性资源和不可抢占性资源

(1)可抢占性资源(可剥夺)

  可把系统中的资源分成两类,一类是可抢占性资源,是指某进程在获得这类资源后,该资源可以再被其他进程或系统抢占。例如优先级高的进程可以抢占优先级低的进程的处理机。又如可把一个进程从一个存储区转移到另一个存储区,在内存紧张时,还可将一个进程从内存调出到外存上,即抢占该进程在内存空间,可见,CPU和主存均属于可抢占性资源。对于这类资源是不会引起死锁了。

(2)不可抢占性资源(非剥夺)

      另一类资源是不可抢占性资源,即一旦系统把某资源分配给该进程,就不能将它强行收回,只能在进程用完后自行释放。例如,当一个进程已开始刻录光盘时,如果突然将刻录机分配给另一个进程,其结果必然会损坏正在刻录的光盘,因此只能等刻好光盘后由进程自己释放刻录机。另外磁带机,打印机等也都属于不可抢占性资源。

  计算机系统中的死锁:

   1.竞争不可抢占性资源引起死锁

    2.竞争可消耗资源引起死锁

    3.进程推进顺序不当引起死锁

二、死锁的定义、必要条件和处理方法:

    

1.死锁的定义:

死锁指两个或多个进程在执行过程中,因争夺资源而陷入相互等待的僵局,若无外力干预,这些进程将无法向前推进。此时,系统处于停滞状态,资源被无效占用。

2.产生死锁的必要条件:

    虽然进程在运行过程中可能会发生死锁,但产生进程死锁是必须具备一定条件的,综上所述不难看出,产生死锁必须同时具备下面四个必要条件,只要其中任一个条件不成立,死锁就不会发生。

(1)互斥条件:进程对所分配到的资源进行排他性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求进程只能等待,直至占用该资源的进程用毕释放。

(2)请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

 (3)不可抢占条件:进程已获得的资源在未使用之前不能被抢占,只能在进程使用完时由自己释放。

 (4)循环等待条件:在发生死锁时,必然存在一个进程——资源的循环链,即进程集合(p0,p1,p2....pn)中的p0正在等待一个p1占用的资源,p1正在等待p2占用的资源,.....,pn正在等待已被p0占用的资源。

3.处理死锁的方法:

  (1)预防死锁

  (2)避免死锁

   (3)检测死锁

   (4)解除死锁

上述的四种方法,从(1)到(4)对死锁的防范程度逐渐减弱,但对应的是资源利用率的提高,以及进程因资源因素而阻塞的频度下降。

   三、避免死锁:

    在死锁避免方法中,把系统的状态分为安全状态和不安全状态。当系统处于安全状态时,可避免发生死锁。反之,当系统处于不安全状态时,则可能进入死锁状态。

     

系统安全状态的定义​

​安全状态(Safe State)​​:
系统存在至少一个​​安全序列(Safe Sequence)​​,使得所有进程都能按此顺序依次获得所需资源并完成执行,而不会导致死锁。

  • ​安全序列​​:假设进程按顺序 P1​,P2​,…,Pn​ 执行,每个进程 Pi​ 的资源请求都可以被当前可用资源满足,且执行完成后会释放所有资源,从而为后续进程提供更多可用资源。

​不安全状态(Unsafe State)​​:
不存在这样的安全序列。此时系统可能进入死锁,但​​不安全状态不一定会导致死锁​​(取决于后续资源请求的实际情况)。

   虽然并非所有非安全状态都必然会转为死锁状态,但当系统进入不安全状态后,就有可能进入死锁状态(不一定)。反之,只要系统处于安全状态,系统便不会进入死锁状态。

    

安全状态的例子​

​场景- ​​资源类型​​:假设系统有 ​​12 个同类型资源​(如内存块)。
  • ​进程​​:3 个进程 P1​,P2​,P3​。
  • ​资源分配状态​​:
    进程最大需求(Max)已分配(Allocated)剩余需求(Need = Max - Allocated)
    P11055
    P2422
    P3927
  • ​当前可用资源​​:12−(5+2+2)=3。
​判断安全状态​
  1. ​初始可用资源​​:3。
  2. ​寻找可进程​​:
    • ​P2 的剩余需求为 2​​ ≤ 可用资源 3 → 可分配。
    • 假设分配给 P2,P2 执行完成后释放资源:可用资源变为 3+2=5。
  3. ​更新可用资源后继续寻找​​:
    • ​P1 的剩余需求为 5​​ ≤ 可用资源 5 → 可分配。
    • P1 执行完成后释放资源:可用资源变为 5+5=10。
  4. ​最后处理 P3​​:
    • ​P3 的剩余需求为 7​​ ≤ 可用资源 10 → 可分配。
    • P3 执行完成后释放资源:可用资源变为 10+2=12。

​安全序列​​:P2​→P1​→P3​(或其他可行顺序)。
​结论​​:系统处于安全状态。

    

不安全状态的例子​

假设在初始状态下,进程 P3​ ​​先请求 1 个资源​​:

​资源分配状态变化​
  • ​已分配资源更新​​:P3 的已分配从 2 → 3,剩余需求从 7 → 6。
  • ​可用资源​​:12−(5+2+3)=2。
进程最大需求已分配剩余需求
P11055
P2422
P3936
​判断是否存在安全序列​
  1. ​初始可用资源​​:2。
  2. ​检查可满足的进程​​:
    • P2 需要 2 ≤ 2 → 分配后可用资源变为 2+2=4。
  3. ​后续检查​​:
    • P1 需要 5 ≤ 4 → ​​不满足​​。
    • P3 需要 6 ≤ 4 → ​​不满足​​。
    • 无其他进程可分配。

​结论​​:无法找到安全序列 → 系统处于不安全状态。
此时系统会拒绝 P3 的资源请求,强制其等待,避免进入不安全状态。

安全状态的实际意义​

  1. ​动态资源分配​​:
    每次资源分配前,系统通过算法(如银行家算法)模拟分配后的状态,仅允许导致安全状态的请求。
  2. ​资源利用率​​:
    安全状态确保资源分配不会因过度保守而浪费,也不会因过度冒险导致死锁。
  3. ​应用场景​​:
    主要用于理论模型或关键系统(如某些数据库管理系统),因实时计算安全状态可能带来性能开销。

       利用银行家算法避免死锁:

1.银行家算法中的数据结构:

   为了实现银行家算法,在系统中必须设置这样四个数据结构,分别用来描述系统中可利用的资源、所有进程对资源的最大需求,系统中的资源分配,以及所有进程还需要多少资源的情况。

(1)可利用资源向量Available。(可分配的)这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值时系统中配置的该类全部可用资源的数目,其数值随该类的资源的分配和回收而动态地改变。如果Available[j] = k,则表示系统中现有Rj类资源 K个。

(2)最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=k,则表示进程i需要Rj类资源的最大数目为K。

 (3)分配矩阵Allocation(已经分配的)  这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j] = k,则表示进程i当前已分得Rj类资源的数目为k。

   (4)需求矩阵Need。这也是一个n*m的矩阵,用来表示每一个进程尚需的各类资源数。如果Need[i,j]=k,则表示进程i还需要Rj类资源K个方能完成其任务。

                                  Need[i,j] = Max[i,j]-Allocation[i,j]

 处理资源请求​

当进程 Pi​ 请求资源时,系统执行以下步骤:

​​Step 1: 检查请求合法性​​

  • Request ≤ Need[i],继续;否则拒绝(非法请求)。

​​Step 2: 检查可用资源是否足够​​

  • Request ≤ Available,继续;否则让进程等待。

一定要先满足上面的两个条件

​Step 3: 模拟分配资源​

  • 临时更新数据:
    • Available=Available−Request
    • Allocation[i]=Allocation[i]+Request
    • Need[i]=]−Request

​Step 4: 执行安全状态检查​

  • 调用安全状态检查算法(见下文)。
  • 如果安全 → 正式分配资源;
  • 不安全 → 撤销模拟分配,让进程等待
安全状态检查算法​

目标:判断是否存在一个​​安全序列​​,使得所有进程都能按顺序完成。

​Step 1: 初始化​

  • 定义两个向量:
    • Work=Available(当前可用资源副本)
    • Finish[1..n]=false(标记进程是否完成)

​Step 2: 寻找可完成的进程​

  • 遍历所有进程,找到满足以下条件的进程 Pi​:
    • Finish[i]=false
    • Need[i]≤Work(即进程的剩余需求 ≤ 当前可用资源)

​Step 3: 模拟进程完成​

  • 若找到 Pi​:
    • Work=Work+Allocation[i](释放其占有的资源)
    • Finish[i]=true
    • 重复 Step 2,直到所有进程完成或找不到可完成的进程。

​Step 4: 判断结果​

  • 如果所有 Finish[i]=true → ​​系统安全​​,存在安全序列;
  • 否则 → ​​系统不安全​​。

具体示例(三种资源类型)​

假设系统有三种资源 R1、R2、R3,初始状态如下:

进程Max (R1, R2, R3)Allocation (R1, R2, R3)Need (R1, R2, R3)
P1(7, 5, 3)(0, 1, 0)(7, 4, 3)
P2(3, 2, 2)(2, 0, 0)(1, 2, 2)
P3(9, 0, 2)(3, 0, 2)(6, 0, 0)
P4(2, 2, 2)(2, 1, 1)(0, 1, 1)
P5(4, 3, 3)(0, 0, 2)(4, 3, 1)

​当前可用资源​​:Available=(3,3,2)(总资源数减去已分配资源)。


​场景:进程 P1 请求资源 (0, 2, 0)​
  1. ​检查合法性​​:
    • Request=(0,2,0)≤Need[P1]=(7,4,3) → 合法。
  2. ​检查可用性​​:
    • Request=(0,2,0)≤Available=(3,3,2) → 合法。
  3. ​模拟分配​​:
    • Available=(3,3,2)−(0,2,0)=(3,1,2)
    • Allocation[P1]=(0,1,0)+(0,2,0)=(0,3,0)
    • Need[P1]=(7,4,3)−(0,2,0)=(7,2,3)
  4. ​安全状态检查​​:
    • ​Step 1​​:初始化 Work=(3,1,2),Finish=[false,false,false,false,false]。
    • ​Step 2​​:寻找可完成的进程:
      • ​P4​​:Need[P4] = (0, 1, 1) ≤ Work = (3, 1, 2) → 符合条件。
    • ​Step 3​​:模拟 P4 完成:
      • Work=(3,1,2)+Allocation[P4]=(2,1,1)→(5,2,3)
      • Finish[P4]=true
    • ​继续寻找​​:
      • ​P2​​:Need[P2] = (1, 2, 2) ≤ Work = (5, 2, 3) → ​​不满足​​(R2分量2 > Work的2)。
      • ​P3​​:Need[P3] = (6, 0, 0) ≤ Work = (5, 2, 3) → ​​不满足​​(R1分量6 > 5)。
      • ​P5​​:Need[P5] = (4, 3, 1) ≤ Work = (5, 2, 3) → ​​不满足​​(R2分量3 > 2)。
      • ​P1​​:Need[P1] = (7, 2, 3) ≤ Work = (5, 2, 3) → ​​不满足​​(R1分量7 > 5)。
    • ​无法完成所有进程​​ → ​​系统不安全​​,拒绝请求!

总结

以上就是今天要讲的内容,我们简单的介绍了一下死锁,包括定义和产生死锁的必要条件,处理死锁的方法,包括详细讲了避免死锁的算法和系统安全状态等等,接下来会持续更新的,谢谢大家。

相关文章:

  • 编译原理 实验二 词法分析程序自动生成工具实验
  • 解决 Ubuntu 上 Docker 安装与网络问题:从禁用 IPv6 到配置代理
  • 【微知】如何将echo某个数据到文件然后cat出来结合在一起输出?(echo 1 | tee filea; cat fileb | tee fila)
  • 【图像生成之22】CVPR024—SwiftBrush基于变分分数蒸馏的文生图扩散模型
  • LeetCode hot 100—不同路径
  • 软考 系统架构设计师系列知识点之杂项集萃(49)
  • 【力扣hot100题】(093)最长公共子序列
  • 基于 Vue 3 + Express 的网盘资源搜索与转存工具,支持响应式布局,移动端与PC完美适配
  • 关于 Spring Boot 监控方式的详细对比说明及总结表格
  • CAN总线发送方每发送一位,接收方接收一位,但是当在非破坏性仲裁方式失利的情况下是否还能够正确接收数据呢?
  • 【C语言-全局变量】
  • Linux:进程优先级的理解
  • 对话记忆(Conversational Memory)
  • 《汽车电器与电子技术》实验报告
  • HotSpot虚拟机中对象的访问定位机制是怎样的?
  • Python实现贪吃蛇一
  • 定制一款国密浏览器(6):初识国密算法
  • sql查询时对null的处理
  • txt、Csv、Excel、JSON、SQL文件读取(Python)
  • Vuex Actions 多参数传递的解决方案及介绍
  • 找人做网站要注意什么/推广联盟平台
  • 备案用的网站建设方案书怎么写/域名归属查询
  • 织梦英文版网站怎么做/seo是什么姓氏
  • 城乡建设官网/郑州seo排名工具
  • 淘宝上买的网站模板怎么建设网站/长沙seo排名优化公司
  • 网站托管/企业网站制作模板