【多线程进阶】死锁问题

news2024/10/7 6:49:43

文章目录

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


前言

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

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

关注收藏, 开始学习吧🧐


1. 什么是死锁

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

1.1 死锁的三种典型情况

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

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

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

在这里插入图片描述

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

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

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

在这里插入图片描述
在哲学家就餐问题中, 五个哲学家就相当于五个线程, 五根筷子就相当于五把锁.

2. 死锁产生的必要条件

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

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

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

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

3.如何解决死锁问题

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

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

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

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


总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1059985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT调用python程序出现问题Failed to get function

问题描述: 1.python中程序运行正常但在QTC的配置中使用Python.h调用python程序时出现Failed to get function问题,去掉python中某个包的应用就可以,比如: python部分程序: import os.path import pandas as pd如果在…

第十二届2023软件杯国家二等奖赛后感想总结

一,相关链接 软件杯官网:软件杯大赛官网 (cnsoftbei.com) 金蝶赛道:金蝶云苍穹开发者门户 (kingdee.com) 二,个人介绍 首先我是个双非院校的学生,专业为计算机科学与技术,打这个比赛是在大二下的暑假开始的…

【10】c++设计模式——>依赖倒转原则

关于依赖倒转原则,对应的是两条非常抽象的描述: 1.高层模块不应该依赖低层模块,两个都应该依赖抽象。 2.抽象不应该依赖细节,细节应该依赖抽象。 先用人话解释一下这两句话中的一些抽象概念: 1.高层模块:可…

【算法练习Day11】滑动窗口最大值前 K 个高频元素

​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 滑动窗口最大值前 K 个高频…

stm32之HAL库操作PAJ75620

一、模块简介 手势模块PAJ7620主要利用IIC或SPI协议来实现数据的传输,本实验用的模块是以IIC来进行信息传输。支持电压从2.8v到3.6v, 正常可以选择3.3v。检测的距离从5到15cm, 可以检测9种手势,包括 右:编码为 0x01左:编码为 0x0…

FDM3D打印系列——黄金弗利萨

大家好,我是阿赵。   国庆期间,在家打印了一个黄金弗利萨的3D模型,和大家分享一下。模型在创想云上面下载的。 使用的设备依然是创想三维的Sermoon V1 Pro,使用的打印材料是创想三维的PLA高速打印素材。 不得不说,…

经典场的量子化

专栏目录: 高质量文章导航-持续更新中-CSDN博客 前置:复指数引起的思考 往指数函数e上丢一个复矢量出来的也是一个复矢量 其定义参考之前的文章群论-李代数_GZVIMMY的博客-CSDN博客 进一步了解下复矢量空间 首先了解下复球面(用一个球表示了所有的复数) 形如[x,y]的二维实…

科普rabbitmq,rocketmq,kafka三者的架构比较

对比 架构对比 从架构可以看出三者有些类似,但是在细节上有很多不同。下面我们就从它们的各个组件,介绍它们: RabbitMQ,是一种开源的消息队列中间件。下面是RabbitMQ中与其相关的几个概念: 1.生产者(P…

微软输入法如何打勾和箭头的符号

文章目录 一、打 “√” 符号二、打 “←” 和 “→” 符号 一、打 “√” 符号 选中 “表情包” 图标 选中 “Ω” 符号后,下拉找到 “√” 即可。 微软输入法打 “ ”这个符号直接输入拼音“cha”就行。 二、打 “←” 和 “→” 符号 拼音直接打 “zuo” 或 “…

GET 和 POST的区别

GET 和 POST 是 HTTP 请求的两种基本方法,要说它们的区别,接触过 WEB 开发的人都能说出一二。 最直观的区别就是 GET 把参数包含在 URL 中,POST 通过 request body 传递参数。 你可能自己写过无数个 GET 和 POST 请求,或者已经看…

扫雷小游戏(简单详细)(内附完整代码)

设计总体思路 实现游戏可以一直玩,先打印棋盘,玩家和电脑下棋,最后分出胜负。 如果编写较大的程序,我们可以分不同模块 例如这个扫雷,我们可以创建三个文件 分别为: game.h 函数的声明game.c 函数的…

《深度不确定条件下的决策:从理论到实践》PDF

制定未来计划时需要预测变化,尤其是制定长期计划或针对罕见事件的计划时。当这些变化存在高度不确定性的时候,这种预期就变得越来越困难。 今天给大家介绍的这本《深度不确定条件下的决策:从理论到实践》正是解决以上问题的良方。完整书籍文…

注意力机制是否比矩阵分解更好?——IS ATTENTION BETTER THAN MATRIX DECOMPOSITION?

原文链接:https://openreview.net/pdf?id1FvkSpWosOlhttps://openreview.net/pdf?id1FvkSpWosOl 代码库:​​​​​​​​​​​​​​GitHub - Gsunshine/Enjoy-Hamburger: [ICLR 2021 top 3%] Is Attention Better Than Matrix Decomposition?[ICL…

苹果ios系统IPA包企业签名手机下载应用可以有几种方式可以下载到手机?

一、App Store签名:这是最常见和推荐的苹果签名方式。用户可以通过苹果的官方应用商店App Store下载并安装经过苹果审核的应用程序。这种签名方式确保了应用程序的安全性和可靠性,因为App Store对应用进行了严格的审核和验证。 二、企业签名:…

三、互联网技术——IP子网划分

文章目录 一、IP地址基础1.1 IP地址分类1.2 网络掩码/子网掩码 二、子网划分VLSM2.1 为什么要进行子网划分2.2 怎么进行子网划分2.3 子网划分原理2.4 例题一2.5 例题二2.6 例题三2.6 例题四2.7 例题五2.8 例题六2.9 例题七2.10 例题八 三、无类域间路由CIDR3.1 例题一3.2 例题二…

基于Android的英语学习软件/英语学习系统

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的APP应运而生,各行各业相继进入信息管理时代&#x…

扩散模型diffusion model 代码解读

代码来自这里 使用pytorch轻松实现简单扩散模型diffusion model(附可跑通全部代码) - 知乎 1.作者首先自己定义了一个数据集,也就是一堆散点,组成的S。 2.这些都是预先设置好的参数,也就是利用这些来做learning的提示…

国庆10.04

服务器 代码 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer> //服务器头文件 #include<QTcpSocket> //客户端头文件 #include<QList> //链表容器 #include<QMessag…

数据结构与算法--算法

这里写目录标题 线性表顺序表链表插入删除算法 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 线性表 顺序表 链表 插入删除算法 步骤 1.通过循环到达指定位置的前一个位置 2.新建…