Linux中死锁问题的探讨
在 Linux 中,死锁(Deadlock) 是指多个进程或线程因为竞争资源而相互等待,导致所有相关进程或线程都无法继续执行的状态。死锁是一种严重的系统问题,会导致系统资源浪费,甚至系统崩溃。
死锁的定义
死锁是指两个或多个进程或线程在执行过程中,因为争夺资源而造成的一种互相等待的现象。如果没有外部干预,这些进程或线程将永远无法继续执行。
死锁的四个必要条件
死锁的发生需要同时满足以下四个条件(称为 Coffman 条件):
互斥条件(Mutual Exclusion):
资源一次只能被一个进程或线程占用。
例如,锁(如互斥锁)就是一种互斥资源。
占有并等待(Hold and Wait):
进程或线程持有至少一个资源,同时等待获取其他被占用的资源。
非抢占条件(No Preemption):
已分配给进程或线程的资源不能被强制剥夺,必须由其自行释放。
循环等待条件(Circular Wait):
存在一个进程或线程的循环链,每个进程或线程都在等待下一个进程或线程所占用的资源。
只有当这四个条件同时满足时,死锁才会发生。
死锁的示例
以下是一个典型的死锁示例:
#include <pthread.h> #include <stdio.h>pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutexB = PTHREAD_MUTEX_INITIALIZER;void* thread1_func(void* arg) {pthread_mutex_lock(&mutexA); // 线程1持有mutexAsleep(1); // 模拟一些操作pthread_mutex_lock(&mutexB); // 线程1尝试获取mutexBprintf("Thread 1 is running.\n");pthread_mutex_unlock(&mutexB);pthread_mutex_unlock(&mutexA);return NULL; }void* thread2_func(void* arg) {pthread_mutex_lock(&mutexB); // 线程2持有mutexBsleep(1); // 模拟一些操作pthread_mutex_lock(&mutexA); // 线程2尝试获取mutexAprintf("Thread 2 is running.\n");pthread_mutex_unlock(&mutexA);pthread_mutex_unlock(&mutexB);return NULL; }int main() {pthread_t tid1, tid2;pthread_create(&tid1, NULL, thread1_func, NULL);pthread_create(&tid2, NULL, thread2_func, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0; }
线程1持有
mutexA
并等待mutexB
。线程2持有
mutexB
并等待mutexA
。两个线程互相等待,导致死锁。
死锁的影响
资源浪费:死锁会导致相关进程或线程无法继续执行,占用系统资源。
系统崩溃:如果死锁涉及关键资源,可能导致整个系统无法正常运行。
难以调试:死锁通常难以复现和调试,尤其是在复杂的多线程程序中。
如何避免死锁
锁顺序:确保所有线程以相同的顺序获取锁。
超时机制:为锁操作设置超时(如
pthread_mutex_timedlock
),避免无限等待。避免嵌套锁:尽量减少锁的嵌套使用。
死锁检测:使用工具或算法检测死锁并采取措施。
资源分配策略:使用资源分配算法(如银行家算法)避免死锁。
死锁检测与恢复
检测:
使用工具(如
gdb
、valgrind
)分析程序运行状态。实现死锁检测算法(如图的环路检测)。
恢复:
强制终止一个或多个进程或线程。
回滚操作,释放资源并重新分配。
线程阻塞
在 Linux 中,死锁和阻塞是两个不同的概念,尽管它们都与资源的竞争和等待有关,但它们的表现和原因有显著区别:
阻塞(Blocking)
定义:阻塞是指一个进程或线程因为等待某个资源(如锁、I/O 操作、信号量等)而暂时无法继续执行,进入等待状态。
原因:
等待获取锁(如互斥锁、读写锁)。
等待 I/O 操作完成(如读取文件、网络数据)。
等待信号量或其他同步机制。
特点:
阻塞是暂时的,一旦资源可用,进程或线程会被唤醒并继续执行。
阻塞是正常的同步机制,用于协调多个进程或线程对共享资源的访问。
阻塞不会导致系统无法运行,只是当前任务暂时停止。
示例:
pthread_mutex_lock(&mutex); // 如果锁被其他线程持有,当前线程会阻塞 // 临界区代码 pthread_mutex_unlock(&mutex);
区别总结
总之,阻塞是正常的同步行为,而死锁是需要避免的系统错误。
线程饥饿
一个线程持有锁一直不释放,其他线程一直在等待这个锁,这种情况不满足锁的四个必要条件,算是死锁吗?
比如如果一个线程持有锁后进入死循环,且其他线程尝试获取该锁。
具体过程:
线程 A 持有锁后进入死循环,永远不会释放锁。
线程 B 尝试获取该锁,但由于锁被线程 A 持有,线程 B 会一直阻塞等待。
如果还有其他线程也尝试获取该锁,它们同样会阻塞等待。
最终,这些线程会因为无法获取锁而永久阻塞
示例代码如下:
#include <pthread.h> #include <stdio.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void* thread_func(void* arg) {pthread_mutex_lock(&mutex); // 线程 A 获取锁while (1) {// 死循环,永远不会释放锁}pthread_mutex_unlock(&mutex); // 这行代码永远不会执行return NULL; }int main() {pthread_t tid;pthread_create(&tid, NULL, thread_func, NULL);pthread_mutex_lock(&mutex); // 主线程尝试获取锁,会一直阻塞printf("This will never be printed.\n");pthread_mutex_unlock(&mutex);pthread_join(tid, NULL);return 0; }
线程 A 获取锁后进入死循环,永远不会释放锁。
主线程尝试获取锁时会被阻塞
这种情况下,虽然不满足死锁的四个必要条件,但它确实会导致类似死锁的现象,通常称为**资源饥饿(Resource Starvation)或活锁(Livelock)**的一种表现。下面详细分析:
1. 这种情况的特点
一个线程持有锁后一直不释放。
其他线程因为无法获取锁而一直等待。
不满足死锁的四个必要条件(特别是循环等待条件),因为没有多个线程相互等待。
2. 为什么不是死锁?
死锁的四个必要条件之一是循环等待,即存在一个进程或线程的循环链,每个进程或线程都在等待下一个进程或线程所占用的资源。而在你的描述中:
只有一个线程持有锁,其他线程在等待这个锁。
没有形成循环等待链,因此不满足死锁的定义。
3. 这种情况的名称
这种情况通常被称为资源饥饿(Resource Starvation):
一个线程独占资源(如锁),导致其他线程无法获取资源,从而无法继续执行。
资源饥饿不一定是死锁,但它会导致系统性能下降或部分功能失效。
总结下线程饥饿和死锁的区别
比较明显的现象就是,线程饥饿时通常会有部分线程还能执行,但是死锁时,涉及到的所有线程都无法执行。
更多参考:
五、面试官:你讲一下线程死锁、饥饿和死循环的区别以及死锁的处理? 我:滔滔不绝...._死锁和循环依赖的区别-CSDN博客
常见问题
死锁、资源饥饿、CPU飙高、内存泄漏、内存溢出、栈溢出
相关文章:

Linux中死锁问题的探讨
在 Linux 中,死锁(Deadlock) 是指多个进程或线程因为竞争资源而相互等待,导致所有相关进程或线程都无法继续执行的状态。死锁是一种严重的系统问题,会导致系统资源浪费,甚至系统崩溃。 死锁的定义 死锁是指…...

【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.3.1 避免频繁更新(Update by Query的代价)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 Elasticsearch数据更新与删除深度解析:2.3.1 避免频繁更新(Update by Query的代价)案例背景1. Update by Query的内部机制解析1.1 文档更…...

【Python项目】基于Python的书籍售卖系统
【Python项目】基于Python的书籍售卖系统 技术简介:采用Python技术、MYSQL数据库等实现。 系统简介:书籍售卖系统是一个基于B/S结构的在线图书销售平台,主要分为前台和后台两部分。前台系统功能模块分为(1)用户中心模…...

spring boot + vue 搭建环境
参考文档:https://blog.csdn.net/weixin_44215249/article/details/117376417?fromshareblogdetail&sharetypeblogdetail&sharerId117376417&sharereferPC&sharesourceqxpapt&sharefromfrom_link. spring boot vue 搭建环境 一、浏览器二、jd…...

Linux下的shell指令(一)
作业 1> 在终端提示输入一个成绩,通过shell判断该成绩的等级 [90,100] : A [80, 90) : B [70, 80) : C [60, 70) : D [0, 60) : 不及格 #!/bin/bash read -p "请输入学生成绩:" score if [ "$score" -ge 90 ] && [ "$scor…...

JS禁止web页面调试
前言 由于前端在页面渲染的过程中 会调用很多后端的接口,而有些接口是不希望别人看到的,所以前端调用后端接口的行为动作就需要做一个隐藏。 禁用右键菜单 document.oncontextmenu function() {console.log("禁用右键菜单");return false;…...
GIt分支合并
分支 1: C0 → C1 → C2 → C3(最新) 分支 2: C0 → C4 → C5 → C6(最新)1. 找到共同父节点 C0 Git 会先找出 branch1 和 branch2 的共同祖先节点 C0。这通常借助 git merge-base 命令达成,虽然在日常使用 git merge…...

Sqli-labs
1.搭建【前提是已经下载安装好phpstudy_pro】 1.1源码准备 1.1.1源码下载 这里从github下载 https://codeload.github.com/Audi-1/sqli-labs/zip/masterhttps://codeload.github.com/Audi-1/sqli-labs/zip/master 1.1.2下载的靶场源码放到WWW下 将刚才下载的压缩包解压到…...
unreal engine gameplay abiliity 获取ability的cooldown剩余时间
unreal engine gameplay abiliity 获取ability的cooldown 版本 5.4.4 参考 测试代码 if (HasAuthority() && AbilitySystemComponent){TArray<FGameplayAbilitySpecHandle> OutAbilityHandles;AbilitySystemComponent->GetAllAbilities(OutAbilityHandles…...
【GenBI优化】提升text2sql准确率:建议使用推理大模型,增加重试
引言 Text-to-SQL(文本转 SQL)是自然语言处理(NLP)领域的一项重要任务,旨在将自然语言问题自动转换为可在数据库上执行的 SQL 查询语句。这项技术在智能助手、数据分析工具、商业智能(BI)平台等领域具有广泛的应用前景,能够极大地降低数据查询和分析的门槛,让非技术用…...

【六祎 - Note】SQL备忘录;DDL,DML,DQL,DCL
SQL备忘录 from to : 点击访问源地址...

高频 SQL 50 题(基础版)_1341. 电影评分
高频 SQL 50 题(基础版)_1341. 电影评分 思路 思路 (select Users.name results from Users left join MovieRating on Users.user_id MovieRating.user_id group by(Users.name) order by count(MovieRating.movie_id) desc,Users.name asc limit 1) u…...
JavaScript 变量命名规范
在编写JavaScript代码时,选择合适的变量名对于代码的清晰度、可读性和可维护性至关重要。一个良好的变量命名规范不仅能帮助团队成员更好地理解代码意图,还能减少错误发生的可能性。本文将介绍一些广泛接受的JavaScript变量命名规则和最佳实践。 命名的…...
解决 uView-UI和uv-ui 中 u-tabs 组件在微信小程序中出现横向滚动条的问题
问题描述 在微信小程序中使用 uView-UI 的 u-tabs 组件时,用户可能会遇到横向滚动条的问题。这不仅影响了页面的美观,还可能导致用户误操作。 问题原因 该问题的根本原因是未在微信小程序环境下屏蔽滚动条。uView-UI 的 u-tabs 组件默认只在 H5 环境下…...

20250304解决在飞凌的OK3588-C的Linux R4下解决使用gstreamer保存的mp4打不开
sync poweroff rootok3588:/# sync rootok3588:/# sync rootok3588:/# cd 107 rootok3588:/107# ls -l total 0 rootok3588:/107# sync rootok3588:/107# poweroff 20250304解决在飞凌的OK3588-C的Linux R4下解决使用gstreamer保存的mp4打不开 2025/3/4 10:58 缘起:…...

build gcc
1,下载源码 wget https://gcc.gnu.org/pub/gcc/infrastructure/mpfr-4.1.0.tar.bz2 wget https://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 wget https://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.2.1.tar.gz git clone --mirror https://github…...
【每日论文】How far can we go with ImageNet for Text-to-Image generation?
下载PDF或查看论文,请点击:LlamaFactory - huggingface daily paper - 每日论文解读 | LlamaFactory | LlamaFactory 摘要 近年来,通过在大规模数据集上训练,文本到图像(T2I)生成模型已经取得了显著成果&a…...

STM32 两个单片机之间的通信
STM32 两个单片机之间的通信 原创 HS 平凡灵感码头 2025年03月04日 11:25 广东 以上我们就是有A B两个板子来进行通信,A板将接收按键的键值,然后发送给B板,B板接收键值,然后判断键值控制LED翻转,然后把键值按字符形式…...
Linux 下使用traceroute来进行网络诊断分析
简介 traceroute 命令是一种网络诊断工具,用于跟踪数据包从系统到目标服务器的路径。它有助于识别网络延迟和路由问题。 安装 Debian/Ubuntu sudo apt install traceroute -yRHEL/CentOS sudo yum install traceroute -yFedora sudo dnf install traceroute -…...

基于vue框架的游戏商城系统cq070(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
系统程序文件列表 项目功能:用户,分类,商品信息,游戏高手,游戏代练 开题报告内容 基于Vue框架的游戏商城系统开题报告 一、研究背景与意义 随着互联网技术的飞速发展和游戏产业的蓬勃兴起,游戏商城作为游戏产业链中的重要一环,迎来了前所…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...