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),避免无限等待。

避免嵌套锁:尽量减少锁的嵌套使用。

死锁检测:使用工具或算法检测死锁并采取措施。

资源分配策略:使用资源分配算法(如银行家算法)避免死锁。

死锁检测与恢复

检测

使用工具(如 gdbvalgrind)分析程序运行状态。

实现死锁检测算法(如图的环路检测)。

恢复

强制终止一个或多个进程或线程。

回滚操作,释放资源并重新分配。

线程阻塞

在 Linux 中,死锁阻塞是两个不同的概念,尽管它们都与资源的竞争和等待有关,但它们的表现和原因有显著区别:

阻塞(Blocking)

定义:阻塞是指一个进程或线程因为等待某个资源(如锁、I/O 操作、信号量等)而暂时无法继续执行,进入等待状态。

原因

等待获取锁(如互斥锁、读写锁)。

等待 I/O 操作完成(如读取文件、网络数据)。

等待信号量或其他同步机制。

特点

阻塞是暂时的,一旦资源可用,进程或线程会被唤醒并继续执行。

阻塞是正常的同步机制,用于协调多个进程或线程对共享资源的访问。

阻塞不会导致系统无法运行,只是当前任务暂时停止。

示例

pthread_mutex_lock(&mutex); // 如果锁被其他线程持有,当前线程会阻塞
// 临界区代码
pthread_mutex_unlock(&mutex);

区别总结

总之,阻塞是正常的同步行为,而死锁是需要避免的系统错误。

线程饥饿

一个线程持有锁一直不释放,其他线程一直在等待这个锁,这种情况不满足锁的四个必要条件,算是死锁吗?

比如如果一个线程持有锁后进入死循环,且其他线程尝试获取该锁。

具体过程:

  1. 线程 A 持有锁后进入死循环,永远不会释放锁。

  2. 线程 B 尝试获取该锁,但由于锁被线程 A 持有,线程 B 会一直阻塞等待。

  3. 如果还有其他线程也尝试获取该锁,它们同样会阻塞等待。

  4. 最终,这些线程会因为无法获取锁而永久阻塞

示例代码如下:

#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飙高、内存泄漏、内存溢出、栈溢出

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

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

相关文章

【基于Mesh组网的UWB技术讨论】

基于Mesh组网的UWB技术讨论 Mesh 组网无线Mesh与无线中继的区别 基于Mesh拓扑的UWB技术可行性星型拓扑 / Mesh拓扑的UWB技术比较 Mesh 组网 Mesh(网格)是一种无中心、自组织的高度业务协同的网络。通常分为无线Mesh和有线Mesh&#xff0c;但在实际应用场景&#xff0c;有线Mes…

Python Cookbook-3.1 计算昨天和明天的日期

任务 获得今天的日期&#xff0c;并以此计算昨天和明天的日期。 解决方案 方案一&#xff1a; 无论何时遇到有关“时间变化”或者“时间差”的问题&#xff0c;先考虑datetime包: import datetime today datetime.date.today() yesterday today - datetime.timedelta(day…

USB 模块 全面解析(二)

本文是我整理的一些 USB 的学习心得&#xff0c;希望能对大家有所帮助。 文章目录 前言&#x1f34d;USB 协议层数据格式&#x1f347;包格式&#x1f353; PID 域&#x1f353; 令牌包&#x1f353; 数据包&#x1f353; 握手包 &#x1f347;传输类型&#x1f353; 批量传输&…

从基础到实践(十):MOS管的全面解析与实际应用

MOS管&#xff08;金属-氧化物半导体场效应晶体管&#xff09;是现代电子技术的基石&#xff0c;凭借高输入阻抗、低功耗和易集成特性&#xff0c;成为数字电路、电源管理和信号处理的核心元件。从微处理器到新能源汽车电驱系统&#xff0c;其高效开关与放大功能支撑了计算机、…

AES/CBC/PKCS5Padding加密

1、加密代码如下 public static String encryptAEs_CBC(String data,String key,byte[] iv) {Cipher cipher = null;try {cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//位数不够,自动补一个长度int blocksize = cipher.getBlockSize();byte[] dataBytes …

指纹细节提取(Matlab实现)

指纹细节提取概述指纹作为人体生物特征识别领域中应用最为广泛的特征之一&#xff0c;具有独特性、稳定性和便利性。指纹细节特征对于指纹识别的准确性和可靠性起着关键作用。指纹细节提取&#xff0c;即从指纹图像中精确地提取出能够表征指纹唯一性的关键特征点&#xff0c;是…

Python 图像处理之 Pillow 库:玩转图片

哈喽,大家好,我是木头左! Pillow 库作为 Python 图像处理的重要工具之一,为提供了便捷且功能丰富的接口,让能够轻松地对图像进行各种操作,从简单的裁剪、旋转到复杂的滤镜应用、图像合成等,几乎无所不能。接下来,就让一起深入探索如何使用 Pillow 库来处理图片,开启一…

Android Flow 示例

在Android开发的世界里&#xff0c;处理异步数据流一直是一个挑战。随着Kotlin的流行&#xff0c;Flow作为Kotlin协程库的一部分&#xff0c;为开发者提供了一种全新的方式来处理这些问题。今天&#xff0c;我将深入探讨Flow的设计理念&#xff0c;并通过具体的例子展示如何在实…

记录uniapp小程序对接腾讯IM即时通讯无ui集成(2)

完成以上步骤之后开始进行登录&#xff0c;登陆就需要账号。这个账号我们可以在腾讯云中创建。 有了账号之后开始去小程序进行登陆操作。腾讯云接口文档 这里除了帐号还需要一个校验值userSig正常项目开发这个字段可以在登陆后让后端返回&#xff0c;现在是测试我们直接去控制…

北京航空航天大学计算机复试上机真题

北京航空航天大学计算机复试上机真题 2023北京航空航天大学计算机复试上机真题 在线评测&#xff1a;https://app2098.acapp.acwing.com.cn/ 阶乘和 题目描述 求Sn1!2!3!4!5!…n!之值&#xff0c;其中n是一个数字。 输入格式 输入一个n&#xff08;n<20&#xff09; …

阿里万相,正式开源

大家好&#xff0c;我是小悟。 阿里万相正式开源啦。这就像是AI界突然开启了一扇通往宝藏的大门&#xff0c;而且还是免费向所有人敞开的那种。 你想想看&#xff0c;在这个科技飞速发展的时代&#xff0c;AI就像是拥有神奇魔法的魔法师&#xff0c;不断地给我们带来各种意想…

算法之数据结构

目录 数据结构 数据结构与算法面试题 数据结构 《倚天村 • 图解数据结构》 | 小傅哥 bugstack 虫洞栈 ♥数据结构基础知识体系详解♥ | Java 全栈知识体系 线性数据结构 | JavaGuide 数据结构与算法面试题 数据结构与算法面试题 | 小林coding

零基础学习之——深度学习算法介绍01

第一节.基础骨干网络 物体分类是计算机视觉&#xff08;computer vision&#xff0c;CV&#xff09;中最经典的、也是目前研究得最为透彻的一 个领域&#xff0c;该领域的开创者也是深度学习领域的“名人”级别的人物&#xff0c;例如 Geoffrey Hinton、Yoshua Bengio 等。物…

弧度与角度之间的转换公式

Radian 弧度的英语 简称 Rad Degree 角度的英语 简称 Deg 角度转弧度 RadDeg*180/π CogMuisc.DegToRad(double degress) DegRad/180*π CogMuisc.RadToDeg(double radians) 总结: 角度大 弧度小 弧度转角度 肯定要乘以一个大于1的数 那就是…

css之英文换行样式

在 CSS 中&#xff0c;要实现英文文本自动换行但不从单词中间断开的效果&#xff0c;可以使用 word-wrap 或 overflow-wrap 属性。以下是相关的 CSS 属性和它们的配置&#xff1a; 使用 overflow-wrap 或 word-wrap /* This property is used to handle word breaking */ .wo…

40岁开始学Java:Java中单例模式(Singleton Pattern),适用场景有哪些?

在Java中&#xff0c;单例模式&#xff08;Singleton Pattern&#xff09;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。以下是详细的实现方式、适用场景及注意事项&#xff1a; 一、单例模式的实现方式 1. 饿汉式&#xff08;Eager Initialization&#xff09; …

【前端基础】3、HTML的常用元素(h、p、img、a、iframe、div、span)、不常用元素(strong、i、code、br)

HTML结构 一个HTML包含以下部分&#xff1a; 文档类型声明html元素 head元素body元素 例&#xff08;CSDN&#xff09;&#xff1a; 一、文档类型声明 HTML最一方的文档称为&#xff1a;文档类型声明&#xff0c;用于声明文档类型。即&#xff1a;<!DOCTYPE html>…

文本挖掘+情感分析+主题建模+K-Meas聚类+词频统计+词云(景区游客评论情感分析)

本文通过情感分析技术对景区游客评论进行深入挖掘,结合数据预处理、情感分类和文本挖掘,分析游客评价与情感倾向。利用朴素贝叶斯和SVM等模型进行情感预测,探讨满意度与情感的关系。通过KMeans聚类和LDA主题分析,提取游客关心的话题,提供优化建议,为未来研究提供方向。 …

【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.2.2线程池配置与写入限流

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 Elasticsearch批量写入性能调优&#xff1a;2.2.2 线程池配置与写入限流深度实践1. 线程池核心机制解析1.1 Elasticsearch线程池架构1.2 Bulk线程池工作模型 2. 写入场景线程…

VSCode 与 Vim 插件 的 复制粘贴等快捷键冲突,优先使用 VSCode 的快捷键

VSCode 与 Vim 插件 的 复制粘贴等快捷键冲突&#xff0c;优先使用 VSCode 的快捷键 在 VSCode 中&#xff0c;如果你发现 Vim 插件&#xff08;如 VSCodeVim 扩展&#xff09;与 VSCode 的默认复制粘贴快捷键&#xff08;CtrlC / CtrlV&#xff09;冲突&#xff0c;并且你想优…