死锁详解和解决办法

死锁概念

死锁是指两个以上线程因争夺资源而发生互相等待的现象!没有外力调解的话,就造成线程一直互相等待,无法执行的情况!

死锁发生的必要条件

死锁发生会同时出现以下的四个必要条件。
1、互斥
一个资源同时只能被一个线程使用

2、请求并保持
线程在请求资源阻塞的时候,并不会释放其已经拥有的资源。

3、不可剥夺
对于线程已经获得的资源,只能线程自己释放,其他线程无法强制剥夺。

4、循环等待
两个或者两个以上线程出现等待资源出现循环依赖。

死锁的解决方法

死锁共有三种解决方式:

1、预防死锁
预防死锁的解决方法就是对上述的四个必要条件的破坏。

1、互斥条件
这个条件一般是无法打破,因为锁大部分的场景就是同时只能允许一个线程获得。

2、请求并保持
防止线程在持有资源后并申请其他资源的情况。

线程一次性申请所有需要的资源。申请成功就运行,不成功就等待。

缺点:线程会提前申请后期运行需要的资源,会导致其他线程无法获取对应的资源,很多时候是其他线程是不会造成死锁的。会造成线程的饥饿,资源的利用率太低。

3、不可剥夺条件
当想要申请新资源并且失败的时候,将当前拥有的资源释放。当新资源可用时,会重新申请之前放弃的资源。

缺点:反复的放弃和申请资源会造成资源的浪费,降低系统的吞吐量。

4、循环等待条件
将所有的资源从小到大编号,线程申请资源按照编号从小到大申请。

比如说进程P1,使用资源的顺序是R1,R2,进程P2,使用资源的顺序是R2,R1,如果采取动态分配的方式,就很有可能造成死锁。我们对设备进行分类编号,那么P1,P2只能以R1,R2的顺序来申请资源。就可以打破环形回路,避免死锁。

缺点:和之前的请求和保持的缺点一致,可能会提前申请不必要的资源,造成资源浪费,造成其他线程的饥饿,降低资源的利用率。

2、避免死锁
预防死锁是通过打破四个死锁必要条件中的一个。

避免死锁不会这么严格要求必须必须打破某个死锁必要条件,因为即使发生了四个死锁中的四个必要条件中的一个,也不一定会发生死锁。

避免死锁相较于预防死锁条件更加宽松。避免死锁的唯一判断条件就是当前线程申请了这个资源,是否会导致死锁。只允许不会造成死锁的线程申请资源。

怎么判断呢?就是通过大名鼎鼎的银行家算法
银行家算法牵扯到以下几个数组和矩阵来统计:
1、可利用的资源数组 Available
记录着资源对应的可利用个数,假如有m个资源,对应的就是一个m维的数组。数组中的数据随着资源的分配和回收波动。

2、最大需求矩阵 Max
记录着线程对于每个资源的最大需求资源个数。为一个n*m的矩阵。n为线程的个数,m为资源的个数

3、已分配矩阵 allocated
记录着为线程对于每个资源的已分配资源个数。为一个n*m的矩阵。n为线程的个数,m为资源的个数

4、需求矩阵 need
记录着线程对于每个资源还需要申请的资源个数,为一个n*m的矩阵,n为线程的个数,m为资源的个数。

银行家算法原理:
当一个线程申请的资源大于可利用资源时,就直接申请失败。
如果申请的资源小于等于可利用资源的时候,就进行安全检测。

检查什么呢?

如果将资源分配给线程后,是否存在一条安全执行序列,使各个线程都能安全执行,不发生死锁。如果存在就给其分配资源。如果不存在就申请失败。

缺点: 必须提前确定线程的最大申请资源个数。

3、死锁的检测和解除
死锁的检测和解除允许系统进入死锁状态。

当线程申请资源的时候,会检测死锁。

如果线程请求资源成功或者尝试请求资源的时候,会将线程和资源信息写入一个结构中,比如map中。

当线程A请求资源的时候,会检测当前拥有资源的线程B是否想要请求线程A当前拥有的资源。

事实上线程B可能会请求其他线程占用的资源。比如线程B请求的资源被线程C占用,而线程C请求的资源被线程D占用,就这样一直递归,直到对应的线程没有请求资源或者对应的线程请求的资源被线程A占用。

如果对应的线程没有请求资源,那么就说明A可以请求资源。
如果对应的线程请求了A占用的资源,说明当前系统发生了死锁,开始解除死锁,比如强制剥夺导致死锁的线程A的对应的资源。

缺点: 撤销死锁线程的代价比较大。某些线程都马上执行结束后,却给撤销了,功亏一篑属实是。

MySQL死锁是指两个或多个事务互相等待对方释放资源而无法继续执行的情况。解决MySQL死锁方法有以下几种: 1. 重试机制:当检测到死锁发生时,可以选择在一段时间后重新尝试执行事务。这样可以避免长时间的等待并解除死锁。 2. 锁超时机制:为每个事务设置一个合理的超时时间。当一个事务在超过设定的超时时间后仍然未能获取到所需的锁,可以选择回滚该事务并释放已获取的资源,以避免死锁的发生。 3. 优化事务并发性:通过合理的事务设计和数据库结构优化,可以减少事务之间的冲突,从而降低死锁的发生率。 4. 调整锁粒度:根据具体情况,可以将锁的粒度调整为表级锁或页级锁,以减少死锁的可能性。但需要注意的是,锁粒度的调整应该是在权衡并发性和数据完整性之间做出的合理选择。 5. 分析并解决死锁:当死锁发生时,可以通过MySQL提供的一些工具和命令来分析死锁的原因,找出造成死锁的具体事务和资源,并进行相应的解决措施,例如撤销某个事务或修改事务执行顺序等。 需要注意的是,不同存储引擎对死锁的处理方式可能会有所不同。因此,在解决MySQL死锁问题时,需要根据具体的存储引擎来选择合适的解决方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [mysql数据库死锁问题处理](https://blog.csdn.net/zy103118/article/details/124823532)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值