【多线程进阶】死锁问题

文章目录

  • 前言
  • 1. 什么是死锁
    • 1.1 死锁的三种典型情况
  • 2. 死锁产生的必要条件
  • 3.如何解决死锁问题
  • 总结


前言

上文锁策略中, 当谈到可重入锁和不可重入锁时, 我们引入了一个 “死锁” 的概念, 当针对一把不可重入锁进行连续两次的加锁行为时, 就会产生死锁.

本文就重点来讲解一下关于死锁的一些知识.

关注收藏, 开始学习吧


1. 什么是死锁

在锁策略中, 我们提到过死锁这一概念, 死锁是这样一种情形: 多个线程同时被阻塞, 它们中的一个或者全部都在等待某个资源被释放. 由于线程被无限期地阻塞, 因此程序不可能正常终止.

1.1 死锁的三种典型情况

1. 一个线程, 一把不可重入锁. 该线程针对这个锁连续加锁两次, 就会出现死锁.
这就是我们上文提到的锁策略中的不可重入锁, 带来的死锁, 是因为针对一把不可重入锁, 连续加锁两次所导致的.

2. 两个线程, 两把锁. 这两个线程先分别获取到一把锁, 然后再同时尝试获取对方的锁.
这个场景其实可以通过生活场景来去理解, 就好比你把车钥匙落家里了, 但是家钥匙又落车里了. 如果你想开家门, 就得先开车门. 想开车门, 就得先开家门. 无限循环形成套娃.

3. 有N个线程, 有M把锁. 这几个线程互相获取锁, 也会有几率出现死锁
很经典的 “哲学家就餐问题” 就是用来描述这个情境的.

【多线程进阶】死锁问题_第1张图片

  • 有一张桌子, 围着一圈 哲学家, 桌子中间放着一盘意大利面. 每个哲学家两两之间, 放着一根筷子.
  • 每个哲学家主要做两件事, 思考人生或者吃面条. 思考人生时, 会放下筷子进行思考. 准备吃面时, 会拿起左手和右手的筷子开始吃面.
  • 每个哲学家, 什么时候思考, 什么时候吃面条, 都是随机的.
  • 每个哲学家一旦准备开始吃面条, 就会非常固执的要完成吃面条的操作, 即便是此时面前筷子被别人占用, 而且等待过程中也不会放下手里已经拿着的一根筷子(拿起一根时, 发现另外一根被别人占用), 开始阻塞等待.

基于以上的设定, 在大部分情况, 这些哲学家都可以很好地开展工作, 去思考, 去吃面条. 但是如果出现了极端情况, 就会发生死锁.

假设同一时刻, 五个哲学家同时拿起左手边的筷子, 然后再尝试拿右手的筷子, 就会
发现右手的筷子都被占用了. 由于哲学家们互不相让, 这个时候就形成了死锁.

【多线程进阶】死锁问题_第2张图片
在哲学家就餐问题中, 五个哲学家就相当于五个线程, 五根筷子就相当于五把锁.

2. 死锁产生的必要条件

在了解死锁出现的几个典型场景后, 请思考一下, 有什么办法能够解决死锁问题呢? 想知道如何解决死锁问题, 我们首先要从根本原因出发, 先明确发生死锁的原因, 明白死锁产生的必要条件是什么.

死锁产生的四个必要条件:

  • 互斥使用, 即当资源被一个线程使用 (占有) 时, 别的线程不能使用.
  • 不可抢占, 资源请求者不能强制从资源占有者手中夺取资源, 资源只能由资源占有者主动释放.
  • 请求和保持, 即当资源请求者在请求其他的资源的同时保持对原有资源的占有.
  • 循环等待, 即存在一个等待队列: P1占有P2的资源, P2占有P3的资源, P3占有P1的资源. 这样就形成了一个等待环路.

当上述四个条件都成立的时候, 便形成死锁. 四个条件缺一不可, 只要能够破坏其中的任意一个条件, 都可以避免出现死锁. 对于我们来说, 其中最容易破坏的就是 “循环等待”.

3.如何解决死锁问题

破坏 “循环等待” 是我们解决死锁问题的关键, 而如何具体的解决死锁问题, 实际的方法有很多, 学过操作系统的读者, 应该都听说过 “银行家算法”, 该算法其实就是用来解决死锁问题的, 不过对于我们来讲, 不够接地气.

在这里, 我们介绍一个, 更加简单, 也可以高效的解决死锁问题的方法 ---- 锁排序.

锁排序就是对锁来进行编号, 并且规定好加锁的顺序, 比如约定, 每个线程如果要获取多把锁, 必须先获取编号小的锁, 后获取编号大的锁. 只要所有线程加锁都严格遵守上述规则, 那么就不会出现 “循环等待” 的这种情况.

在上述哲学家就餐问题中, 我们只要约定好, 从一到五, 给每个筷子都设置一个编号, 所有哲学家, 拿筷子时先拿编号小的筷子, 再拿编号大的筷子, 这样就不会出现我们说的那种极端情况了.


总结

✨ 本文主要讲解了一些死锁的概念, 重点介绍了死锁的几种典型场景, 以及死锁产生的几个必要条件, 并且讲述了如何去解决死锁问题.
✨ 想了解更多的多线程知识, 可以收藏一下本人的多线程学习专栏, 里面会持续更新本人的学习记录, 跟随我一起不断学习.
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习.

再次感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!

你可能感兴趣的:(多线程学习之路,数据库,安全,死锁,多线程,哲学家问题)