<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>死锁 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E6%AD%BB%E9%94%81/</link><description>Recent content in 死锁 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 04 May 2026 16:28:56 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E6%AD%BB%E9%94%81/index.xml" rel="self" type="application/rss+xml"/><item><title>死锁（Deadlock）原理、常见场景与治理</title><link>https://amatsuzero.github.io/LastStand/posts/interview/ios-performance/deadlock-%E6%AD%BB%E9%94%81/</link><pubDate>Mon, 04 May 2026 16:28:56 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/interview/ios-performance/deadlock-%E6%AD%BB%E9%94%81/</guid><description>&lt;p&gt;死锁是 iOS 多线程开发中最隐蔽、也最致命的一类稳定性问题。它不像越界、空指针那样&amp;quot;立刻崩溃给你看&amp;quot;，而是表现为主线程&amp;quot;卡住&amp;quot;——用户能感受到界面无响应、无法交互，最终被 iOS watchdog 强杀（&lt;code&gt;0x8BADF00D&lt;/code&gt;），落在 Apple 崩溃日志里归为 &lt;code&gt;EXC_CRASH (SIGKILL)&lt;/code&gt; 或卡死（Hang）。&lt;/p&gt;
&lt;p&gt;本文系统梳理死锁的&lt;strong&gt;四个必要条件&lt;/strong&gt;、iOS 生产环境中&lt;strong&gt;常见的发生场景&lt;/strong&gt;，并结合 Apple 官方工具（TSan、Main Thread Checker、MetricKit）与业界最新实践（Sentry App Hangs、字节 Heimdallr、Swift Concurrency 的反思）讨论&lt;strong&gt;如何检测与治理&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一死锁是什么"&gt;一、死锁是什么&lt;/h2&gt;
&lt;p&gt;死锁（Deadlock）指两个或多个线程因争夺资源（锁、队列、信号量等）而互相等待，导致所有相关线程永久阻塞、无法推进的状态。&lt;/p&gt;
&lt;p&gt;与死锁容易混淆的几个概念：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;核心特征&lt;/th&gt;
&lt;th&gt;典型例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;死锁 Deadlock&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;多个线程循环等待对方持有的资源，永久阻塞&lt;/td&gt;
&lt;td&gt;线程 A 持 lockA 等 lockB；线程 B 持 lockB 等 lockA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;活锁 Livelock&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;线程不阻塞但也不推进，不停重试互相让步&lt;/td&gt;
&lt;td&gt;两个线程都检测到冲突就回退重试，永远撞在一起&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;饥饿 Starvation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;低优先级线程长期分不到资源&lt;/td&gt;
&lt;td&gt;高优先级线程持续抢占 CPU，导致低优先级线程持锁永远运行不完&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;优先级反转 Priority Inversion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;低优先级持锁 + 高优先级自旋等锁 + 中优先级抢 CPU，高优先级被间接阻塞&lt;/td&gt;
&lt;td&gt;&lt;code&gt;OSSpinLock&lt;/code&gt; 被废弃的根本原因&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;死循环 Busy Loop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;单线程进入无限循环，CPU 占用 100%&lt;/td&gt;
&lt;td&gt;&lt;code&gt;while(true)&lt;/code&gt; 忘记 break&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;卡顿 Hang&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;主线程执行时间超过阈值（几百 ms～几秒）&lt;/td&gt;
&lt;td&gt;主线程做网络、解压大图、Core Data 大量 fetch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;卡死 Watchdog&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;主线程卡住数秒（启动约 20s、前后台切换约 10s），触发系统强杀&lt;/td&gt;
&lt;td&gt;死锁导致的卡死是最严重的一种&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;关键区别&lt;/strong&gt;：死循环线程 CPU 占用高、处于 &lt;code&gt;RUNNING&lt;/code&gt; 态；死锁线程 CPU 占用为 0、处于 &lt;code&gt;WAITING/BLOCKED&lt;/code&gt; 态并被换出。这一点正是线上死锁自动判定的核心依据（见&amp;quot;检测&amp;quot;章节）。&lt;/p&gt;</description></item></channel></rss>