/* Page prose (zh-Hans) */
"Deadlock" = "# 死锁：永远地等待你自己\n\n**死锁**是指工作永久地停止，因为任务们在一个圈里互相等待，谁也动不了。最简单的版本只需要一条队列和一个词：`sync`。\n\n回想一下，`sync` 的意思是*“运行这个块，在它完成之前不要返回。”*现在来看那个经典的冻结。在主线程上运行时，我们 `sync` 到主队列上：\n\n```swift\n// ⚠️ DO NOT RUN THIS: it deadlocks the main thread forever.\nimport Foundation\n\nDispatchQueue.main.sync {\n    print(\"This line never runs.\")\n}\n```\n\n走一遍逻辑：\n\n1. 你在主线程上。你调用 `main.sync { ... }`。\n2. `sync` 说：“我就在这里等，直到那个块完成。”\n3. 但这个块被安排在**主队列**上运行，而主队列正是那个此刻冻结在 `sync` 里、正在等待的线程。\n4. 主线程在等待这个块；而这个块在主线程空闲之前无法开始。谁都不肯让步。**冻住了。**\n\n这是一场只有一个参与者的循环等待。每当你 `sync` 到**一条你已经在其上运行的串行队列**时，同样的陷阱就会触发：\n\n```swift\n// ⚠️ DO NOT RUN THIS EITHER: same deadlock, different disguise.\nimport Foundation\n\nlet ledger = DispatchQueue(label: \"ledger\")   // serial\n\nledger.sync {\n    // We are now running *on* ledger...\n    ledger.sync {          // ...and we ask it to run something and wait.\n        print(\"Unreachable.\")   // ledger is busy with us. Circular wait.\n    }\n}\n```\n\n我们把有竞争的例子拿去实时运行，是因为一个错误的数字是无害的。我们**不**运行这些，因为死锁什么都不打印；它只会把 Playground 页面挂起，直到你手动停止它。这正是这条规则值得记住的原因：\n\n**永远不要调用 `sync` 去针对你已经在其上的那条队列。特别是，永远不要从主线程调用 `DispatchQueue.main.sync`。**\n\n`async` 没有这个问题：它把块交出去然后立即返回，所以没有人站在那儿干等。当你需要弹回主队列去更新 UI 时，永远用 `DispatchQueue.main.async`。\n\n[上一页](@previous)  |  第 6 / 9 页  |  [下一页: 优先级反转](@next)";
