死锁 + 条件变量 + 生产消费者模型

文章目录

    • 死锁
      • 如何解决死锁问题呢?
      • 避免死锁
    • 同步
    • 条件变量
    • 生产消费者模型

死锁

现象 : 代码不会继续往后推进了

问题
一把锁有没有可能产生死锁呢?
有可能
在这里插入图片描述
线程第一次申请锁成功,继续再次申请,第二次申请就失败了,当前线程抱着锁就被挂起了
其他线程申请都失败阻塞了。
1.你抱着锁去休眠了
2.没有人释放锁了
3. 剩余线程申请锁都不成功
所有整个线程全部都卡住了

上面是单执行流,单锁,更一般的情况是多锁,多执行流

一组执行流(这里按多线程说),并发编程时锁可能不止一个,正常编程时各个线程都由调度器自由去申请锁,此时就可能出现问题,一个线程持有一把锁,另一个线程持有另一把锁,但是他们两个却互相申请对方的锁,进而导致一种永久等待的状态,这种状态成为死锁。

所有的死锁都是由于程序员代码写的不太合适或者调度过程中出现异常问题

例子
张三和李四去商店买糖,他们俩每人只有五毛钱,但是棒棒糖一块钱,张三要李四的那五毛,
李四要张三那五毛,他们两个人就在商店这里卡住了。

多线程会产生死锁其实有四个必要条件
什么叫必要条件?
只要产生了死锁必定满足这四个条件,并不代表使用这四个条件百分百产生死锁
反过来理解
只要四个条件中有一个条件不满足就一定不会产生死锁

1.互斥条件
要有死锁的前提肯定是要先用了锁
2.请求与保持条件
比如例子中张三请求李四的五毛钱并且不释放自己的五毛,李四也遵循相同的规则
3.不剥夺条件
张三拿着自己的五毛钱还在请求对方的五毛,但不能强行抢李四的五毛
4.循环等待条件
若干执行流之间形成一种头尾相接的循环等待资源的关系
在这里插入图片描述
我们写的抢票就是遵循互斥条件,有请求与保持,只不过只有一把锁,也有不剥夺条件,但是没产生死锁
因为必须形成环路等待才能产生死锁
在这里插入图片描述

如何解决死锁问题呢?

理念
一旦有死锁必定要同时满足四个必要条件,解决的话必然需要破坏4个必要条件之一

方法
1.代码死锁了,那我重写一下代码我不用锁了那就没有互斥了也没有死锁了

2.请求与不保持
张三问李四要五毛失败了,此时张三把五毛释放了,反正张三也走不到后面买不了棒棒糖
具体怎么操作呢?
之前pthread_mutex_lock 线程申请锁失败后不是立马出错返回而是把自己阻塞住
pthread_mutex_trylock 申请锁如果失败它会立即返回,是申请锁的非阻塞版本
它返回后把锁释放掉然后从新开始申请锁,这样就很容易破坏请求与保持条件
我们用的lock本来就是保持的,你不给我锁我就在这阻塞住,只不过只有一把锁

3.破坏不剥夺条件,那就是要剥夺,剥夺的本质不就是释放对方的锁吗
怎么剥夺呢?
直接释放锁
以前讲解锁的原理不是把以前交换的锁换回去,而是直接把锁置1 了

第一条破坏改动比较大,2,3是通过接口可以实现的

4.环路等待问题,申请资源形成一个环路
在这里插入图片描述

要破坏它通过编码来完成
张三要李四的锁2,李四要张三的锁1,为什么会这样?
谁让你申请锁时不按顺序申请而是交叉着申请,为什么不让两个线程同时申请锁1然后再同时申请锁2。
也就是说你要同时持有两把锁你必须得按顺序申请锁,也就破坏了环路等待问题

避免死锁

破坏死锁的四个必要条件

加锁顺序保持一致
两个线程都按顺序申请锁1锁2,不要倒着来,尽可能减少环路等待

避免锁未释放的场景
写代码锁要尽快释放

资源一次性分配
尽量把资源一次性给线程,不要让线程花了多次持有锁申请资源
一次给它,意味着加锁场景少一些,产生死锁场景就少了

同步

条件变量

生产消费者模型

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从纸笔到屏幕:我的CS笔记记录体验分享

前言 三年大学生活里,我花了很多时间在记录笔记上,也因为现有种类繁多的各种学习方式,和朋友一起走了很多弯路。纸笔,OneNote,Typora…… 想总结分享一下自己大学期间的学习笔记记录方式(主要针对计算机学…

不同的葡萄品种的葡萄酒有什么共同特质?

在某种程度上几乎所有的葡萄酒都是混合的,在大多数葡萄酒产地,法律允许在单一品种葡萄酒中混入高达15%的另一种葡萄酒,且还能被称为由主要葡萄酿造的单一品种葡萄酒酒。这些单一品种葡萄酒混合了少量其他葡萄酒,是为了创造一个特质…

centos离线安装mosquitto

1.x86_64架构centos7操作系统mosquitto包 本次真正要安装的机器是x86_64架构的AMD Ryzen 3 ,操作系统是centos7 先找一台能联网的centos7机器 添加 EPEL 软件库 yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm下载rpm包 …

【DataSophon】大数据管理平台DataSophon-1.2.1基本使用

🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁&am…

通过WinCC基本功能实现批次查询及批次报表

谈到WinCC中的批次数据处理和批次报表,也许有人会想到PM-Quality这款专业的批次报表软件。但如果你的银子有限,批次报表要求又比较简单,不妨看看此文。 —《通过 WinCC 基本功能实现批次数据过滤查询以及打印批次数据报表》 实现的功能描述 …

中通单号查询,中通快递物流查询,对需要的单号进行备注

批量查询中通快递单号的物流信息,对需要的单号进行备注。 所需工具: 一个【快递批量查询高手】软件 中通快递单号若干 操作步骤: 步骤1:运行【快递批量查询高手】软件,并登录 步骤2:点击主界面左上角的“…

华为OD机试真题-查找一个有向网络的头节点和尾节点-2023年OD统一考试(C卷)

题目描述: 给定一个有向图,图中可能包含有环,图使用二维矩阵表示,每一行的第一列表示起始节点,第二列表示终止节点,如[0, 1]表示从0到1的路径。每个节点用正整数表示。求这个数据的首节点与尾节点&#xf…

linux(centos7)离线安装mysql-5.7.35-1.el7.x86_64.rpm-bundle.tar

1. 卸载mariadb相关rpm # 查找 rpm -qa|grep mariadb rpm -qa|grep mysql# 卸载 rpm -e --nodeps mariadb... rpm -e --nodeps mysql...2. 删除mysql相关文件 # 查找 find / -name mysql# 删除 rm -rf /var/lib/mysql...3. 查看是否有相关依赖,没有需安装 rpm -q…

RocketMQ源码 Broker-SubscriptionGroupManager 订阅组管理组件源码分析

前言 SubscriptionGroupManager 继承了ConfigManager配置管理组件,拥有将内存数据持久化到磁盘文件subscriptionGroup.json的能力。它主要负责维护所有消费组在内存中的订阅数据。 源码版本:4.9.3 源码架构图 核心数据结构 主要的数据结构比较简单&am…

微信小程序使用camera扫码获取相机权限

确保用户隐私指引已经明确使用相机功能 “mp-weixin”: "permission": {"scope.camera": {"desc": "需要使用相机功能,请授权"}}wx.authorize({scope: scope.camera,success(res) {console.log(res, 用户成功授权)// 用户…

基于虚拟机下的win7系统安装简记

文章目录 安装系统激活win7提示系统保留分区未分配驱动器问题使用win7 Active激活系统根据dns分配的ip地址将网络改为固定ip,然后关闭防火墙,即可完成虚拟机与宿主机互通 安装系统 在虚拟机中找到自己下载win7镜像文件,配置完成后一路next即…

Docker 部署 Lobe Chat 服务

拉取最新版本的 Lobe Chat 镜像: $ sudo docker pull lobehub/lobe-chat:latest使用以下命令来运行 Lobe Chat 容器: $ sudo docker run -d --name lobe-chat -p 10084:3210 -e OPENAI_API_KEYsk-xxxx -e OPENAI_PROXY_URLhttps://api.openai.com/v1 -e ACCESS_CO…