死锁的发生与预防

死锁的概念

在多线程环境下,为了避免资源的竞争,通常我们会给资源加上互斥锁,谁拿到这个锁谁就有资格享有这个资源。

当一个 A 进程申请资源时,如果这个时候没有可用的资源,那么这个进程会进入等待状态。如果所申请的资源被其他进程 B 占有,并且该进程也在等待进程 A 的资源,那么在这种各自都在等待对方释放锁,你等我,我等你的情况,就可能永远都无法释放锁。这种情况称为死锁(deadlock)

死锁的必要条件

要发生死锁,那就需要同时满足四个条件:

  • 互斥(mutual exclusion) :同一个资源不可被多个进程所共享。
  • 占有并等待(hold and wait) :如果进程 A 发现想要的资源已经被进程 B 占有了,那么此时进程 A 应该等待进程 B 的资源释放,与此同时进程 A 所拥有的资源不应该释放,而是持续占有。
  • 非抢占(no preemption):已经被进程占有的资源,不可被其他进程强行抢占,只能等待该资源被所持有的进程主动释放。
  • 循环等待(circular wait):有一组等待进程 等待的资源为 所占有, 等待的资源为 所占有, 等待的资源为 所占有。

死锁的预防

死锁需要成立需要同时满足四个条件。那么只需要确保至少有一个条件不成立就不会发生死锁。

互斥

互斥条件必须成立!

在多线程环境下,必须保证同一份共享资源只能同时给一个线程访问。

因为如果共享资源不要求互斥访问,那么就不会产生死锁,但同时也就没法保证数据的安全性。

占有并等待

打破这种条件的方案:

  1. 每个线程在执行前就申请到所有资源。
  2. 在线程没有资源时才申请资源,已有资源时则不再申请。也就是说,在申请更多其他资源之前,应该先释放线程本身已有的资源。

缺点:

  • 资源利用率较低,因为一次分配到了所有所需资源,但并不是立刻使用,导致其他所需要这些资源的线程无法继续任务。
  • 进程容易处于饥饿状态,因为一直申请不到全部资源。

非抢占

打破这种条件的方案:

  • 如果一个线程所持有的资源,并同时申请另一个不能立即分配到的资源(也就是说,该线程应该等待该资源被释放),那么该线程所分配到的所有资源都可以被抢占!

具体的说,如果一个线程申请了一些资源,那么首先会检查资源是否可用:

  • 如果资源可用,则分配他们。
  • 如果资源不可用,那么就从持有该资源的等待线程(等待队列)中抢占,并分配给申请线程。如果没有从等待队列中找到持有该资源的线程,那么申请线程将进入等待队列。
  • 只有当一个线程分配到申请的资源,并恢复在等待时被抢占的资源时,才能重新执行。

为什么只有等待队列中的线程可以被抢占? 因为在等待队列中的线程还没有执行,所以被抢占了也不影响。

alt

特别注意,这种破坏只适用于 CPU 寄出去、数据库事务这种状态可以轻松保存会恢复的资源

  • 为什么?因为在等待线程被抢占,那么就需要具备:当线程恢复了,不会对资源(现场)造成任何影响。
  • 如果抢占了不具备状态恢复能力的资源,那么当线程恢复后,现场可能不一样。

不适用于互斥锁和信号量之类的资源,因为这些资源恰恰是最经常发生死锁的资源。

  • 为什么?因为需要用到互斥锁和信号量的资源,那都是共享资源。
  • 如果抢占了这类资源,那么临界区数据就会被破坏,如链表修改到一半,结果被抢占了,导致数据结构被破坏了。

循环等待

打破这种条件的方案:

  • 为所有资源分配一个唯一整数编号,并对这些资源进行排序。
  • 而且要求每个线程都要按照递增所需来申请资源。

由于资源只能按照编号递增申请,等待关系不可能形成环,因此循环等待不会发生。

例如:

P1 -> R1
P2 -> R3
P2 -> R4
P1 -> R2

每个进程已有的资源 ,在申请新的资源 时,必须满足

好处:

  • 资源利用率相对于前面两种方式较高。(不会一次申请全部资源,也不会频繁释放)

缺点:

  • 各类资源的顺序与系统规定的顺序有绝对影响

  • 当程序使用资源的顺序与系统规定的不同的,就会造成资源浪费。

    例如,进程 A 要先使用打印机,然后才使用磁盘。(而系统规定顺序:) 那么进程 A 就必须先获取磁盘,而不能先获取打印机。此时,由于进程 A 提取占用了未来才使用到的资源,导致其他需要这个磁盘资源的进程无法继续任务,只能等待磁盘资源的释放。这就造成了资源浪费。

  • 编程复杂,程序员必须要清楚系统所有资源的顺序,才可以编写高效的程序。

  • 新设备编号引入可能会打乱原有资源的顺序。

死锁的预防所存在的问题

《死锁的预防》主要是通过“限制资源的申请方式”来预防死锁。这种限制确保了至少有一个死锁必要条件不会发生。而通过这种方式来预防死锁也有缺点:

  • 设备利用率低
  • 系统吞吐率低

另外一种避免死锁的方式,这种方法需要先知道一些信息,基于这些信息来预测以及避免死锁。

针对每次申请要求,系统在做决定时考虑如下资源情况:

  • 现有可用资源
  • 已经分配的资源
  • 每个进程将来申请与释放的资源

安全状态

安全状态是死锁避免中很重要的一个概念。

  • 安全状态(Safe State):至少存在一个进程序列,按照这个序列申请资源,使得每个进程都能获得所需资源,完成执行、释放资源,从而允许其他进程最终完成而不进入死锁。
  • 不安全状态(Unsafe State):尽管系统仍然可以向某些进程分配资源,但无法保证所有进程都能完成而不可能引发死锁。

常见的两种算法

  • 资源分配图算法
  • 银行家算法
#面试##操作系统#
全部评论
各位牛友感觉有没有什么地方不理解的?或者需要画图的,需要的话我可以多画几张。
1 回复 分享
发布于 今天 14:29 广东

相关推荐

03-11 20:19
已编辑
门头沟学院 Java
太压力了,面了2个多小时,本菜比已经被拷打的瑟瑟发抖面完两个小时后通知过了1.算法题三道(1)leetcode124 二叉树中最大路径和hard题 因为不久前才刷过撕出来了,又来了一道(2)leetcode 300 最长递增子序列变种除了递增之外还加了一个权重因素,但是思路没变,dp就行(3)寻找词汇库里符合固定长度前缀的匹配单词应该是他们自己题库的题。给了一串单词列表,然后又给了一个单词,一个下标,根据这个下标的前缀去单词列表里面找到所有匹配的单词再返回思路是创建一个单词前缀树,然后根据树找,但是可能是构件树数有问题没撕出来2.全方位项目拷打基本没有问八股,全部都是项目企业场景题,哎哟我操,完全不会。我就纯八股战士,结果没想到一道八股都没问反正尽可能把企业场景往八股上引吧。。1. 微服务多点部署其中一个宕机了怎么办2. 要是mq占据大量CPU该怎么排查?MySQL占据大量CPU该怎么排查?3. 假如说让你实现视频点赞功能,你打算怎么设计?讲讲思路(我知道多级缓存,但是碰巧没背……寄)4. Redis延迟双删是什么,分布式锁,哨兵模式5. MySQL到es同步的延迟该怎么优化6. Rabbit mq的队列是怎么实现的?(这个完全没整明白,可能是队列的底层结构? 反正我硬扯的讲了一下rabbit mq的架构)还扯了很多,但是往后完全就慌了),记住的是这些
不知道怎么取名字_:2小时确实有压力,持续性的脑力劳动啊
查看9道真题和解析
点赞 评论 收藏
分享
03-14 21:33
已编辑
东莞理工学院 Java
📍面试公司:好未来🕐面试时间:03/14💻面试岗位:golang后端开发❓面试问题:1. Go 的基本数据类型有哪些?2. 什么是值类型和引用类型,分别有哪些?3. slice 底层结构和扩容机制是什么?4. map 底层基于什么实现,是有序还是无序?5. 对 Go 的 channel 怎么理解?6. channel 一般用在什么业务场景?7. 无缓冲和有缓冲 channel 的区别是什么?8. 如何深拷贝 slice,避免多个变量互相影响?9. Redis 适用哪些业务场景?10. 为什么 Redis 单线程还能支持高并发?11. epoll 在 Redis 中用在什么场景?12. Redis 的 key 过期策略有哪些?13. Redis 过期删除后内存会立刻释放吗?14. Redis 内存满了有哪些淘汰策略?15. Redis 持久化方案有哪些?16. RDB 和 AOF 区别是什么?17. Redis 高可用方案有了解吗?18. Redis 主从、哨兵、集群的区别?19. ES 主要适用于什么场景?20. 业务数据(如订单)能不能存在 ES?21. 多表数据聚合同步到 ES 怎么实现?22. ES 集群健康状态有哪几种,分别代表什么?23. ES 设置分片和副本,允许节点宕机数量怎么判断?24. Kafka 和 RocketMQ 的区别是什么?25. Kafka 为什么会出现消息丢失?26. 如何避免 Kafka 消息丢失?27. Kafka 的 at least once 机制是什么?28. 业务层如何保证消息不丢失、最终一致?29. MySQL 事务隔离级别有哪些?30. MySQL 默认隔离级别是什么?31. 可重复读的含义是什么?32. 什么场景会使用不同的事务隔离级别?33. InnoDB 可重复读是怎么实现的?34. MySQL 有哪些存储引擎,区别是什么?35. MyISAM 适用什么业务场景?36. 联合索引的最左匹配原则是什么?37. MySQL 默认索引类型是什么,和哈希索引区别?38. 多表关联查询、聚合查询如何设计索引?39. 研发工程师应该如何应对和使用 AI?40. 使用 AI 编程工具有哪些风险?41. 怎么避免 AI 生成代码带来的线上问题?42. 平时用什么开发工具和 AI 模型?43. 使用 AI 辅助开发遇到过哪些问题,怎么解决?44.手撕sql包括建立索引等等🙌面试感想:感动坏了,春招以来最舒服的一场面试,大部分问题都回答出来了,并且面试官在你回答出来了之后,还会给予正反馈说没错,你说的对,然后记不太清楚的问题,他还会给予提示,然后告诉你该怎么去回答,并且给出他的看法,也是一天直接速通了两面下周三约HR面
发面经攒人品
点赞 评论 收藏
分享
点赞 评论 收藏
分享
昨天 10:59
已编辑
美团_后端开发(实习员工)
爱写代码的菜code...:哎,自己当时拿到字节offer的时候也在感叹终于拿到了,自己当时最想去的企业就是字节,结果还是阴差阳错去了鹅厂。祝uu一切顺利!!!
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务