死锁是指两个或多个进程(或线程)因竞争资源而陷入相互等待的永久阻塞状态,若无外部干预,无法继续推进 。例如,线程A持有资源X并等待资源Y,而线程B持有资源Y并等待资源X,形成循环等待的僵局。
死锁的产生需同时满足以下四个条件,缺一不可 :
通过破坏四个必要条件之一来避免死锁发生 :
通过动态判断资源分配的安全性,确保系统始终处于安全状态 :
Need = Max - Allocation。Need矩阵。Work = Available,表示当前可用资源。Finish,初始值为False,表示所有进程尚未完成。P_i:
Finish[i] == False(进程未完成)。Need[i] <= Work(进程所需的资源不超过当前可用资源)。P_i执行完毕并释放资源,更新:
Work = Work + Allocation[i](可用资源增加)。Finish[i] = True(标记进程完成)。Finish[i] == True,说明所有进程都能顺利完成,系统处于安全状态。假设系统有3类资源(A、B、C),初始可用资源Available = [3, 3, 2],有5个进程,资源分配如下:
进程 | Allocation | Max | Need (Max - Allocation) |
|---|---|---|---|
P0 | 0 1 0 | 7 5 3 | 7 4 3 |
P1 | 2 0 0 | 3 2 2 | 1 2 2 |
P2 | 3 0 2 | 9 0 2 | 6 0 0 |
P3 | 2 1 1 | 2 2 2 | 0 1 1 |
P4 | 0 0 2 | 4 3 3 | 4 3 1 |
步骤:
Work = [3, 3, 2],Finish = [False, False, False, False, False]。P1(Need[1] = [1, 2, 2] <= Work),执行并更新:
Work = [3, 3, 2] + [2, 0, 0] = [5, 3, 2]。Finish[1] = True。P3(Need[3] = [0, 1, 1] <= Work),执行并更新:
Work = [5, 3, 2] + [2, 1, 1] = [7, 4, 3]。Finish[3] = True。P4(Need[4] = [4, 3, 1] <= Work),执行并更新:
Work = [7, 4, 3] + [0, 0, 2] = [7, 4, 5]。Finish[4] = True。P0(Need[0] = [7, 4, 3] <= Work),执行并更新:
Work = [7, 4, 5] + [0, 1, 0] = [7, 5, 5]。Finish[0] = True。P2(Need[2] = [6, 0, 0] <= Work),执行并更新:
Work = [7, 5, 5] + [3, 0, 2] = [10, 5, 7]。Finish[2] = True。Finish为True,系统处于安全状态。银行家算法通过模拟资源分配过程,确保系统始终处于安全状态,避免死锁。其核心是找到一个安全序列,使所有进程都能顺利完成。虽然算法严谨,但由于需要预知进程的最大资源需求,实际应用中主要用于理论研究和特定场景(如数据库管理系统)。
Monitor.TryEnter),超时后释放已有资源 允许死锁发生,但通过检测和恢复机制处理 :
READ COMMITTED)以减少锁冲突 。SHOW ENGINE INNODB STATUS分析死锁日志并优化SQL 方法 | 核心思想 | 适用场景 |
|---|---|---|
预防 | 破坏必要条件,牺牲部分灵活性和效率 | 对实时性要求较低的系统 |
避免 | 动态判断资源分配的安全性(如银行家算法) | 资源类型固定的批处理系统 |
检测恢复 | 允许死锁发生,事后通过终止进程或抢占资源恢复 | 复杂系统或无法预知的场景 |
注:实际系统中常结合多种方法。例如,数据库通过超时机制(避免)和死锁检测(恢复)综合应对 ,而编程中则优先通过顺序加锁(预防)和减少锁粒度来降低风险
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。