绝望的拥抱:深度解析死锁与解决方案

news/2025/11/29 17:58:56/文章来源:https://www.cnblogs.com/irobotzz/p/19287147

🛑 绝望的拥抱:深度解析死锁与解决方案

🛑 绝望的拥抱:深度解析死锁与解决方案

写在前面
所谓死锁,不是“程序死了”,而是“程序互相卡住了”。

就像两个人在独木桥中间相遇:
甲说:“你退后,让我先过。”
乙说:“不,你退后,让我先过。”
既没有人退后(不可剥夺),也没人能飞过去(互斥),两人就这样大眼瞪小眼,直到天荒地老。


一、 死锁的概念

死锁是指两个或两个以上的进程(或线程),在执行过程中,因争夺资源而造成的一种互相等待的现象。如果没有外力干涉,它们都将无法推进下去。

它不同于“死循环”——死循环是 CPU 跑满了但不干正事;死锁是 CPU 没什么负载,但程序就是不动了


二、 核心理论:死锁产生的 4 个必要条件

这是计算机科学领域的铁律。只有同时满足这 4 个条件,死锁才会发生。 只要破坏其中任意一个,死锁就会解开。

条件 专业术语 通俗解释 (Details Matter)
1 互斥条件 (Mutual Exclusion) “它是我的”。资源是独占的,同一时刻只能有一个线程持有。如果有别人想用,只能等。
2 持有并等待 (Hold and Wait) “吃着碗里的,看着锅里的”。我手里已经拿着资源 A 了,我不释放 A,同时我还想要申请资源 B。
3 不可剥夺 (No Preemption) “我凭本事抢的,凭什么给你”。资源只能由持有者主动释放,别人不能强行抢走。
4 环路等待 (Circular Wait) “爱的魔力转圈圈”。A 等 B,B 等 C ... C 等 A,形成了一个封闭的逻辑闭环。

三、 模拟死锁问题的产生 (微观视角)

为了让你看清死锁,我们设计一个经典的 “转账死锁” 场景。
假设有两个账户:User A 和 User B。

  • 线程 1:要把钱从 A 转给 B。它需要先锁住 A,再锁住 B。
  • 线程 2:要把钱从 B 转给 A。它需要先锁住 B,再锁住 A。

1. 代码逻辑 (Java/伪代码)

// 资源对象
Object lockA = new Object();
Object lockB = new Object();// 线程 1
Thread t1 = new Thread(() -> {synchronized (lockA) { // 1. 拿到 A 锁System.out.println("T1: 拿到 A, 准备去拿 B");sleep(100); // 【关键细节】:休息一下,让出 CPU,给 T2 机会运行synchronized (lockB) { // 2. 想要 B 锁 (卡住!)System.out.println("T1: 转账成功");}}
});// 线程 2
Thread t2 = new Thread(() -> {synchronized (lockB) { // 3. 拿到 B 锁System.out.println("T2: 拿到 B, 准备去拿 A");// 没 sleep 也可能死锁,但加了 sleep 必死无疑synchronized (lockA) { // 4. 想要 A 锁 (卡住!)System.out.println("T2: 转账成功");}}
});

2. 死锁形成的时间轴 (Timeline)

请仔细看这个执行顺序,这就是环路形成的瞬间:

  1. T1 时刻:线程 1 启动,成功拿到 lockA
  2. T2 时刻:线程 1 调用 sleep持有 lockA 不放,但让出了 CPU。
  3. T3 时刻:线程 2 获得 CPU,启动,成功拿到 lockB
  4. T4 时刻:线程 2 尝试去拿 lockA
    • 系统判定lockA 正被线程 1 拿着呢,且不可剥夺
    • 结果:线程 2 进入阻塞状态,抱着 lockBlockA
  5. T5 时刻:线程 1 醒来,尝试去拿 lockB
    • 系统判定lockB 正被线程 2 拿着呢。
    • 结果:线程 1 进入阻塞状态,抱着 lockAlockB

最终结局:T1 等 T2 放手,T2 等 T1 放手。环路形成,程序挂起。

graph TDT1((线程 1))T2((线程 2))RA[资源 A]RB[资源 B]T1 --持有--> RARA --被请求--> T2T2 --持有--> RBRB --被请求--> T1style T1 fill:#f9f,stroke:#333style T2 fill:#f9f,stroke:#333style RA fill:#5f5,stroke:#333style RB fill:#5f5,stroke:#333linkStyle 1 stroke:red,stroke-width:2px;linkStyle 3 stroke:red,stroke-width:2px;

四、 利用工具排查死锁

当线上服务突然卡死,日志不输出,CPU 占用也不高,怎么确定是死锁?

1. Java 程序员的神器:jstack

JDK 自带的命令行工具。

  • 命令jstack <PID> (PID 是进程 ID)

  • 输出分析:它会打印所有线程的堆栈。直接拉到最后,如果存在死锁,它会明确告诉你:

    Found one Java-level deadlock:
    =============================
    "Thread-0":waiting to lock monitor 0x00007f... (object 0x00000007...) -> 也就是 Lock Blocked ownable synchronizer 0x00007f... (object 0x00000006...) -> 也就是 Lock A
    "Thread-1":waiting to lock monitor 0x00007f... (object 0x00000006...) -> 也就是 Lock Alocked ownable synchronizer 0x00007f... (object 0x00000007...) -> 也就是 Lock B
    

    看到 "Found one Java-level deadlock" 字样,实锤了。

2. C++/Linux 程序员:pstack + gdb

  • 使用 pstack <PID> 查看调用栈,你会发现几个线程都停在 lock()wait() 函数上不动了。

3. 数据库死锁:SHOW ENGINE INNODB STATUS

  • 如果你是 MySQL 出现死锁,执行这条 SQL,数据库会把最近一次死锁的详细日志打印出来。

五、 怎么避免死锁? (核心方案)

只要破坏 4 个必要条件中的任意一个,就能避免死锁。

1. 破坏“持有并等待” —— 一次性申请所有资源

  • 策略:要么全有,要么全无。
  • 实现:线程开始运行前,必须一次性申请到 Lock A 和 Lock B。如果拿不到 Lock B,就连 Lock A 也不要拿。
  • 缺点:资源利用率低。可能我很久以后才用 B,但我一开始就占着茅坑。

2. 破坏“不可剥夺” —— 拿不到就放手

  • 策略:如果我申请不到新资源,我就把手里的旧资源释放掉,过一会再重试。
  • 实现:使用 Lock.tryLock() (Java/C++) 机制。
    • tryLock() 会尝试加锁,成功返回 true,失败返回 false(不会阻塞)。
    • 如果失败了,执行 else 逻辑:释放已持有的锁,休眠随机时间,重试。

3. 破坏“环路等待” —— 资源有序分配 (最常用、最推荐)

这是工业界解决死锁的金科玉律

  • 策略:给所有资源编号(1, 2, 3...)。规定:所有线程必须按照从小到大的顺序申请资源。
  • 应用到转账场景
    • 我们根据 UserID 进行排序。
    • 规定:必须先锁 ID 小的账户,再锁 ID 大的账户。
    • User A (id=10) 转给 User B (id=20):先锁 A,再锁 B。
    • User B (id=20) 转给 User A (id=10)依然是先锁 A,再锁 B
  • 效果:线程 1 和线程 2 都会去抢 Lock A。谁抢到了,谁就执行;没抢到的在第一步就阻塞了,根本不会拿到 Lock B,从而彻底杜绝了环路的形成。

4. 银行家算法 (Banker's Algorithm)

  • 概念:这是操作系统层面的理论算法。在分配资源前,先预演一下“如果我给了你这个资源,系统会不会进入不安全状态”。如果会,就不给你。
  • 现状:开销太大,实际业务开发中几乎不用,面试时知道名字即可。

⚡️ 总结

  1. 死锁是并发编程中的“交通瘫痪”,本质是环路等待
  2. 4 个条件缺一不可:互斥、持有并等待、不可剥夺、环路等待。
  3. 排查:Java 用 jstack,C++ 用 gdb,数据库看日志。
  4. 预防 (记住这一条就够了)按顺序加锁。给资源排序,永远按固定顺序申请锁,这是最简单也最有效的方案。

至此,关于进程、线程、并发、通信、死锁的操作系统核心五部曲就讲解完毕了。如果你对内存管理(虚拟内存、页面置换)感兴趣,我们可以开启新的篇章! 👨‍💻

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

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

相关文章

2025年12月 DeepSeek、豆包AI营销服务商推荐TOP5

豆包和DeepSeek的推广价值源于其快速增长的用户基础和精准的智能分发能力。作为字节跳动和深度求索公司分别推出的AI助手,豆包和DeepSeek均已迅速积累数千万用户,在国内AI大模型市场中占据重要地位。其用户群体涵盖技…

最短路网络

学长 Mikakoko 在 ICPC 比赛中退役了,根据惯例,他要写一篇小作文(手动滑稽)。最短路相关的问题太多啦,这篇小作文只能简单介绍其中的一部分。 在连通的无向正权图上,给定源点 \(S\),我们能计算得到所有 \(\text…

2025年管片T型螺栓,管廊T型螺栓,光伏T型螺栓厂家盘点:精密工艺与工程案例解析

2025年管片T型螺栓,管廊T型螺栓,光伏T型螺栓厂家盘点:精密工艺与工程案例解析在2025年的紧固件市场中,邯郸市时方硕紧固件有限公司是一家备受瞩目的企业。该公司坐落于紧固件产业集聚地,是一家专注于高端紧固件及…

2025 年合肥摄影培训人像摄影培训推荐榜:路人贾摄影讲堂(合肥分公司)人像领域排名第一

随着影像社交时代的全面到来,无论是职业摄影师、时尚从业者还是摄影爱好者,对于高品质人像摄影技能的需求持续升温。专业、系统、实战性强的摄影培训课程,已成为提升个人或团队竞争力的关键投资。市场上摄影培训机构…

2025年高铁T型螺栓,铝型材T型螺栓,管廊T型螺栓厂家推荐:安装便捷性与兼容性测评

2025年高铁T型螺栓,铝型材T型螺栓,管廊T型螺栓厂家推荐:安装便捷性与兼容性测评在各类工程建设中,T型螺栓的作用至关重要,尤其是高铁、铝型材以及管廊建设领域。2025年,在众多T型螺栓厂家中,邯郸市时方硕紧固件…

2025年管片螺栓,螺纹管片螺栓,双头管片螺栓厂家推荐:资质认证与工程案例深度解读

2025年管片螺栓,螺纹管片螺栓,双头管片螺栓厂家推荐:资质认证与工程案例深度解读在建筑与工程领域,管片螺栓、螺纹管片螺栓以及双头管片螺栓等紧固件的质量至关重要,它们直接关系到工程的稳定性与安全性。邯郸市时…

2025年弧形管片螺栓,六角管片螺栓,螺纹管片螺栓厂家推荐:实测数据与隧道工程优选

2025年弧形管片螺栓,六角管片螺栓,螺纹管片螺栓厂家推荐:实测数据与隧道工程优选在隧道工程建设中,弧形管片螺栓、六角管片螺栓以及螺纹管片螺栓等紧固件的质量和性能至关重要,它们直接关系到隧道结构的稳定性和安…

深入解析:当 AI 视觉遇上现代 Web:DeepSeek-OCR 全栈应用深度剖析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年欧标T型螺栓,地铁专用T型螺栓,高铁T型螺栓品牌榜:资质认证与工程适配解析

2025年欧标T型螺栓,地铁专用T型螺栓,高铁T型螺栓品牌榜:资质认证与工程适配解析在2025年的紧固件市场中,欧标T型螺栓、地铁专用T型螺栓以及高铁T型螺栓等产品的市场需求持续增长。对于众多工程建设项目而言,选择合…

113.Java深入学习之JVM一

113.Java深入学习之JVM一引入:之前过多的的项目去做 实际上是空洞的学习 大概这个缘故早就有了 不过一次面试问了一些原理性的问题彻底成为导火索 首先确实反感那些深层次原理的理解 因为实际中更多的是如何解决问题即…

可能是 noip2025 退役记

我将发挥我的主观能动性放弃放弃放弃 退役退役退役 再见再见再见 我亲爱的OI

2025年工业脚轮,轻型脚轮,脚轮万向轮推荐:聚焦安装孔距,适配性实测解析

2025年工业脚轮,轻型脚轮,脚轮万向轮推荐:聚焦安装孔距,适配性实测解析在工业领域,脚轮作为设备移动的关键部件,其性能和适配性至关重要。2025年,随着工业的不断发展,对脚轮的要求也越来越高。今天,我们将聚焦…

从浏览器访问地址到看到页面信息经历的过程

以搜索"人工智能"为例,从输入URL到页面显示,百度背后经历了7 大核心步骤: URL解析 → DNS域名解析 → TCP连接(HTTPS握手) → HTTP请求发送 → 百度服务器处理 → 响应返回 → 浏览器渲染URL解析(浏览器…

软件技术基础第三次作业

1.博客基本信息项目 内容这个作业的目标 以小组为单位,完成一个“电梯演讲”作业姓名-学号 徐增乐-2023329301026 魏路琦-2023329301033这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/25rjjc/homework/1…

2025年工业脚轮,设备脚轮,轻型脚轮厂家推荐:聚焦安装适配性,全场景选型攻略

2025年工业脚轮,设备脚轮,轻型脚轮厂家推荐:聚焦安装适配性,全场景选型攻略在工业领域,脚轮虽小,却起着至关重要的作用。无论是工业设备的移动,还是轻型物品的搬运,合适的脚轮都能提高工作效率,降低劳动强度。…

2025年静音脚轮,设备脚轮,周转车脚轮厂家推荐:核心性能解析,适配场景全攻略

2025年静音脚轮,设备脚轮,周转车脚轮厂家推荐:核心性能解析,适配场景全攻略在2025年,如果您正在寻找优质的静音脚轮、设备脚轮和周转车脚轮,那么青岛大世汇豪脚轮有限公司绝对值得关注。这家自2005年成立以来已稳…

复杂业务逻辑的数据筛选:多维表格条件嵌套能力的技术解析

作为技术或业务岗,你是否曾为一串“与或非”条件反复创建中间字段?比如市场部提需求:“筛出买过A没买B的VIP,或30天内咨询A且来自高价值渠道的未下单客户”。这种复杂筛选,恰恰是多维表格的能力试金石。今天拆解蜘…

2025年轻型脚轮,静音脚轮,设备脚轮厂家权威推荐:聚焦使用场景,品质测评榜单

2025年轻型脚轮,静音脚轮,设备脚轮厂家权威推荐:聚焦使用场景,品质测评榜单在工业设备的运行中,脚轮虽小却起着至关重要的作用,它直接影响着设备的移动便利性和使用体验。在众多脚轮厂家中,青岛大世汇豪脚轮有限…

2025年减震脚轮,设备脚轮,工业脚轮厂家推荐榜:聚焦承重静音,品质红榜盘点

2025年减震脚轮,设备脚轮,工业脚轮厂家推荐榜:聚焦承重静音,品质红榜盘点在工业领域中,脚轮作为设备移动的关键部件,其质量和性能直接影响着设备的使用效率和寿命。尤其是减震脚轮、设备脚轮和工业脚轮,它们在不…

2025年南京单招集训,高职单招培训,泰达单招集训中心推荐:聚焦教学实力与升学服务的测评指南

2025年南京单招集训,泰达单招集训中心测评指南在2025年的高职单招备考之路上,选择一家靠谱的单招集训中心至关重要。泰达教育作为一家拥有正规民办办学资质的教育培训机构,在高职单招领域深耕多年,凭借多方面的优势…