死锁 (Deadlock) 深度解析 - 详解

news/2025/10/25 16:53:26/文章来源:https://www.cnblogs.com/lxjshuju/p/19165629

目录

1. 什么是死锁?一个生活中的比喻

2. 死锁的四个必要条件(科夫曼条件)

a. 互斥 (Mutual Exclusion)

b. 持有并等待 (Hold and Wait)

c. 不可抢占 (No Preemption)

d. 循环等待 (Circular Wait)

3. 如何处理死锁?

死锁预防:破坏四个必要条件之一

4. C++ 标准库提供的“死锁安全带”

std::lock 和 std::scoped_lock (C++17)


1. 什么是死锁?一个生活中的比喻

想象一个场景:在一个狭窄的单行道上,两辆车迎面相遇。

  • 车A 想要前进,但被 车B 挡住了。

  • 车B 也想前进,但被 车A 挡住了。

两辆车都占着自己当前的路(持有资源),同时又在等待对方让出道路(请求资源)。如果两位司机都互不相让,他们就会永远卡在这里,谁也动不了。这种情况,就是死锁

在并发编程中,“车”就是线程,“道路”就是资源(最常见的是互斥锁 std::mutex)。

死锁的正式定义:指两个或多个并发线程,在执行过程中因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

2. 死锁的四个必要条件(科夫曼条件)

一个死锁的发生,必须同时满足以下全部四个条件。只要破坏其中任意一个,死锁就不会发生。

a. 互斥 (Mutual Exclusion)
  • 定义:一个资源在同一时刻只能被一个线程持有。如果其他线程想使用该资源,必须等待直到资源被释放。

  • 比喻:打印机在任何时候只能打印一个人的文件。在你打印完成之前,其他人必须等待。

  • 编程体现std::mutex 本身就是互斥的。lock() 操作确保了只有一个线程能进入临界区。这个条件在并发编程中通常是无法避免的,因为我们就是需要用锁来保护共享资源。

b. 持有并等待 (Hold and Wait)
  • 定义:一个线程至少持有一个资源,并且正在请求另一个被其他线程持有的资源。在等待新资源的同时,它并不会释放自己已经持有的资源。

  • 比喻:你手里拿着一支笔(持有资源1),现在你需要一张纸来写字,但纸在另一个人手里。你在等待他给你纸的同时,并没有放下你手中的笔。

  • 编程体现

    std::lock_guard lock1(mtx1); // 持有 mtx1
    // ...做一些事...
    std::lock_guard lock2(mtx2); // 等待 mtx2
c. 不可抢占 (No Preemption)
  • 定义:资源不能被强制地从持有它的线程中“抢”走。只能由持有者在完成任务后自愿释放。

  • 比喻:别人不能从你手里强行夺走你正在使用的笔。你必须自己决定什么时候用完并把它放下。

  • 编程体现:当一个线程通过 lock() 获得了互斥锁,操作系统或其他线程无法强制它 unlock()。它必须自己执行到作用域结束(对于 lock_guard)或手动调用 unlock()

d. 循环等待 (Circular Wait)
  • 定义:存在一个线程的等待链,形成一个闭环。

    • 线程 T1 正在等待线程 T2 持有的资源。

    • 线程 T2 正在等待线程 T3 持有的资源。

    • ...

    • 线程 Tn 最终等待线程 T1 持有的资源。

  • 比喻

    • 想借小明的钢笔,但小明说必须先借到小红的笔记本才行。

    • 小红说,她必须先借到的橡皮擦,才肯借出笔记本。

    • 于是,你等小明,小明等小红,小红又在等你。三个人陷入了无限的循环等待。

  • 最经典的编程场景

    // 线程 1
    void func1() {std::lock_guard lock1(mtx1); // 1. 锁住 mtx1std::this_thread::sleep_for(std::chrono::milliseconds(10));std::lock_guard lock2(mtx2); // 2. 尝试锁住 mtx2 (等待线程2释放)
    }
    // 线程 2
    void func2() {std::lock_guard lock2(mtx2); // 1. 锁住 mtx2std::this_thread::sleep_for(std::chrono::milliseconds(10));std::lock_guard lock1(mtx1); // 2. 尝试锁住 mtx1 (等待线程1释放)
    }

    如果 func1func2 并发执行,func1 可能锁住 mtx1 等待 mtx2,而 func2 同时锁住了 mtx2 等待 mtx1,这就形成了循环等待,导致死锁。

3. 如何处理死锁?

主要有三种策略:预防、避免、检测与恢复。在应用级编程中,我们最关心的是死锁预防

死锁预防:破坏四个必要条件之一

预防死锁的核心思想,就是通过编码规范和设计,来破坏四个必要条件中的至少一个。

  • 破坏“互斥”

    • 方法:允许多个线程同时访问资源。

    • 可行性:很低。对于打印机、共享计数器这类资源,我们就是为了互斥才加锁的。但对于只读数据,可以使用无锁数据结构或原子操作 std::atomic 来代替互斥锁。

  • 破坏“持有并等待”

    • 方法:规定线程在请求资源前,不能持有任何其他资源。要么一次性申请所有需要的资源,要么在申请新资源前,先释放已持有的所有资源。

    • 可行性:较低。很难预知一个任务到底需要哪些资源,且“先释放再申请”可能导致线程活锁(不断尝试但总失败)。

  • 破坏“不可抢占”

    • 方法:允许系统或优先级更高的线程抢占资源。

    • 可行性:极低。在应用层面几乎无法实现,且会使程序逻辑变得异常复杂。

  • 破坏“循环等待” (最实用、最常用的策略)

    • 方法对所有资源(互斥锁)进行全局排序,并强制所有线程都必须按照这个统一的顺序来获取锁。

    • 可行性:非常高,是预防死锁的黄金法则

    • 比喻:规定所有司机在十字路口都必须先让右边的车。这样就不会出现所有车都想抢先而堵死的局面。

    • 编程实现

      std::mutex mtx1, mtx2;
      // 假设我们规定,必须先锁地址较小的互斥量
      // 这是一个全局统一的顺序
      // 线程 1
      void func1_fixed() {// 总是按 mtx1 -> mtx2 的顺序加锁std::lock_guard lock1(mtx1);std::lock_guard lock2(mtx2);
      }
      // 线程 2
      void func2_fixed() {// 同样遵守 mtx1 -> mtx2 的顺序std::lock_guard lock1(mtx1);std::lock_guard lock2(mtx2);
      }

      通过强制所有线程都遵循 mtx1 -> mtx2 的加锁顺序,就打破了循环等待的可能性,从根本上消除了死锁。

4. C++ 标准库提供的“死锁安全带”

手动管理锁的顺序很麻烦且容易出错。为此,C++ 标准库提供了更高级的工具来自动处理这个问题。

std::lockstd::scoped_lock (C++17)

当你需要同时锁定多个互斥锁时,应该使用它们。

  • std::lock(mtx1, mtx2, ...): 这是一个函数,可以一次性、无死锁地锁定传入的所有互斥锁。它内部实现了一套避免死锁的算法(例如,它会尝试锁定,如果某个锁失败了,它会解开所有已锁定的锁,然后重试)。

  • std::scoped_lock(mtx1, mtx2, ...) (C++17, 最佳选择): 这是一个 RAII 风格的类,是 std::lock 的现代化封装。它在构造时自动调用 std::lock 来安全地锁定所有互斥锁,在析构时(离开作用域时)自动将它们全部解锁。

#include 
#include 
std::mutex mtx_A, mtx_B;
void safe_operation() {// 只需要一行代码,就能安全、无死锁地锁定两个互斥锁// 无需关心 mtx_A 和 mtx_B 的顺序std::scoped_lock lock(mtx_A, mtx_B);// ... 在此作用域内,mtx_A 和 mtx_B 都被安全锁定 ...// ... 执行你的操作 ...
} // lock 析构时,会自动解锁 mtx_A 和 mtx_B

结论:在需要同时锁定多个互斥锁的场景下,永远优先使用 std::scoped_lock。这是现代 C++ 中预防死锁的最佳实践。

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

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

相关文章

解压小猫

小花猫世界 - 主页 一只桌面宠物

2025年家具厂家推荐排行榜:实木家具、定制家具、办公家具、软体家具、智能家具源头厂家精选

2025年家具厂家推荐排行榜:实木家具、定制家具、办公家具、软体家具、智能家具源头厂家精选 随着消费升级和居住理念的转变,家具行业正迎来新一轮发展机遇。实木家具以其天然环保的特性持续受到青睐,定制家具凭借个…

2025 厨房排烟安装公司最新推荐榜:实力品牌服务与工艺解析及选择指南饭店/商用/罩/系统/厨房排烟管道专业服务公司推荐

引言 厨房排烟系统安装质量直接关系商用厨房的安全运营与人员健康,但行业内 38% 的企业存在工艺不规范问题,27% 使用劣质材料导致故障频发。为破解选择难题,本次联合中国商用厨具协会开展权威测评,参照 T/CAS848-2…

2025年仿石漆厂家推荐排行榜,外墙仿石漆,内墙仿石漆,防霉仿石漆,水包水/水包砂仿石漆,耐污自洁仿石漆公司精选

2025年仿石漆厂家推荐排行榜:外墙仿石漆、内墙仿石漆、防霉仿石漆、水包水/水包砂仿石漆、耐污自洁仿石漆公司精选 在建筑装饰材料领域,仿石漆凭借其卓越的装饰效果和实用性能,已成为现代建筑外墙与内墙装饰的重要选…

权威调研榜单:苏州吊车租赁公司TOP3榜单好评深度解析

随着长三角地区基建项目持续推进,苏州吊车租赁市场需求显著增长。据行业数据显示,2025年苏州地区吊车租赁规模同比提升18%,其中起重吊装、龙门吊租赁、登高车租赁三类业务占比超60%。本文基于对企业设备规模、服务能…

从零开始制作 MyOS(二)

从零开始制作 MyOS(二) 目标 一个简单的,能打印出字符串的 boot 已经做完了,那么接下来做一个加载多个磁盘扇区的功能。 原因 BIOS 在找到一个可引导设备后,加载该引导设备的第一个扇区,也就是扇区号为 0 的扇区…

【Linux网络】Socket编程:UDP网络编程达成ChatServer

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

完整教程:告别内网困局:cpolar破解Websocket远程访问难题

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

2025 年钛白粉源头厂家最新推荐排行榜:高分子材料领域专家解析改性技术与行业应用案例

引言 本次钛白粉源头厂家推荐排行榜,是结合中国化工协会高分子材料专业委员会 2024 - 2025 年度测评数据生成,测评覆盖全国 23 个省份共 86 家钛白粉生产企业,采用 “技术实力 + 产品质量 + 服务能力 + 市场口碑” …

如何通过限制网络访问来降低服务器被攻击的风险? - 指南

如何通过限制网络访问来降低服务器被攻击的风险? - 指南2025-10-25 16:38 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important;…

2025 年泳池设备厂家推荐:Firsle 法思乐泳池水处理与海洋馆维生系统设备专业方案及一体化设备优势解析

行业背景 近年来,居民生活品质提升推动私家泳池、民宿泳池需求持续增长,文旅产业扩张带动大型商业泳池、海洋馆项目密集落地,市场对水处理设备的专业性、稳定性与智能化要求显著提高。传统设备普遍存在安装流程复杂…

Axure: 多级多选可交互树状列表 - 指南

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

2025年工业木托盘批发厂家权威推荐榜单:实木叉车托盘/物流木托盘/免熏蒸木托源头厂家精选

在物流与供应链效率至关重要的今天,工业木托盘作为仓储运输的基础载体,其质量直接关系到整个物流系统的安全与效率。 根据市场调研数据显示,2025年华东地区标准化托盘使用率将突破68%,其中无锡作为苏南物流集散中心…

2025年废气治理设备厂家推荐排行榜,废气处理设备,工业废气净化装置,有机废气处理系统公司精选

2025年废气治理设备厂家推荐排行榜:工业废气净化装置与有机废气处理系统公司精选 随着环保政策的日益严格和工业绿色转型的加速推进,废气治理设备市场正迎来前所未有的发展机遇。工业废气净化装置和有机废气处理系统…

2025年托辊输送带直销厂家权威推荐榜单:输送机托辊/托辊设备/托辊配件源头厂家精选

在工业输送系统领域,托辊作为关键部件,其质量直接影响输送带的运行效率和使用寿命。据行业报告显示,2025年中国输送机托辊市场容量已达数十亿元级别,全球市场预计在预测期内将以稳定增长率持续扩大。 在工业输送系…

2025年提升机厂家权威推荐榜:自动提升机、垂直提升机、斗式提升机,高效输送设备源头厂家精选

2025年提升机厂家权威推荐榜:自动提升机、垂直提升机、斗式提升机,高效输送设备源头厂家精选 在工业自动化快速发展的今天,提升机作为物料输送系统的核心设备,其性能直接影响生产效率和运营成本。自动提升机、垂直…

2025 年最新冲压油供应厂家权威榜单:聚焦空调加工适配性与免清洗技术,助力企业精准选品免清洗/铝翅片/定子转子/高速冲压油厂家推荐

引言 在空调制造行业,翅片冲压油的品质对生产至关重要。为给企业提供可靠选择,中国制冷空调工业协会联合行业专家开展 2025 年翅片冲压油供应厂家测评。测评采用 “三维九项” 体系,从产品性能(润滑性、冷却性、抗…

ttkefu与下一代人机协同客服:重塑服务生态的智能引擎

ttkefu与下一代人机协同客服:重塑服务生态的智能引擎 在数字化浪潮与人工智能技术深度融合的当下,客户服务领域正经历一场由“人机协同”驱动的革命性变革。作为全渠道智能客服系统的标杆,ttkefu凭借其前瞻性的技术…

2025年企业数字化展厅定制厂家权威推荐榜单:企业数字展厅/企业创意展厅/企业智能展厅源头厂家精选

在数字化浪潮的推动下,企业展厅已从静态展示空间逐步升级为集智能交互、数据可视化和沉浸式体验于一体的战略枢纽,成为企业品牌建设与数字化转型的关键一环。 本文将基于行业技术实力、项目案例积累、全流程服务能力…

2025年仿石漆厂家推荐排行榜,外墙仿石漆,真石漆,质感涂料,水包砂,仿石涂料优质供应商精选

2025年仿石漆厂家推荐排行榜:外墙仿石漆、真石漆、质感涂料、水包砂、仿石涂料优质供应商精选 在建筑装饰材料领域,仿石漆凭借其卓越的装饰效果和实用性能,已成为外墙装饰的主流选择。随着2025年的到来,建筑行业对…