【Linux】死锁

news/2025/2/14 3:24:38/

文章目录

    • 死锁
    • 关于阻塞的理解
    • 死锁的四个必要条件
    • 避免死锁的方法

死锁

死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待状态

单执行流可能导致死锁问题吗?

可能!例如:某一个执行流连续申请了两次锁,那么此时该执行流就会被挂起

原因:

  • 因为该执行流第一次申请锁的时候是申请成功的,但第二次申请锁时因为该锁已经被申请过了,于是申请失败导致被挂起直到该锁被释放时才会被唤醒
  • 但是这个锁本来就在自己(该执行流)手上,自己现在处于被挂起的状态根本没有机会释放锁,所以该执行流将永远不会被唤醒,此时该执行流也就处于一种死锁的状态

证明:

我们让主线程创建的新线程连续申请了两次锁

#include<stdio.h>
#include<pthread.h>
pthread_mutex_t mut;//互斥锁void* Routine(void* args)
{pthread_mutex_lock(&mut);pthread_mutex_lock(&mut);
}int main()
{pthread_t tid;pthread_mutex_init(&mut,NULL);//初始化互斥锁pthread_create(&tid,NULL,Routine,NULL);//创建新线程pthread_join(tid,NULL);//等待新线程pthread_mutex_destroy(&mut);//释放互斥锁return 0;
}

此时该程序实际就处于一种被挂起的状态

image-20220826171309526

ps命令查看该进程时可以看到,该进程当前的状态是Sl+,其中的l实际上就是lock的意思,表示该进程当前处于一种死锁的状态

image-20220826171427026


关于阻塞的理解

什么是阻塞?

进程运行时是被CPU调度的,换句话说进程在调度时是需要用到CPU资源的,每个CPU都有一个运行等待队列,CPU在运行时就是从等待队列中获取进程进行调度的

image-20220826174709555


在运行等待队列中的进程本质上就是在等待CPU资源,实际上不止是等待CPU资源如此,等待其他资源也是如此,比如锁的资源、磁盘的资源、网卡的资源等等,它们都有各自对应的资源等待队列

image-20220826174732829

情形:当某一个进程在被CPU调度时,该进程需要用到锁的资源,但是此时锁的资源正在被其他进程使用

1)此时该进程的状态就会由R状态变为某种阻塞状态(例如:S状态),并且该进程会被移出运行等待队列,被链接到等待锁的资源的资源等待队列,而CPU则继续调度运行等待队列中的下一个进程

2)此后若还有进程需要用到这一个锁的资源,那么这些进程也都会被移出运行等待队列,依次链接到这个锁的资源等待队列当中

3)直到使用锁的进程已经使用完毕,也就是锁的资源已经就绪,此时就会从锁的资源等待队列中唤醒一个进程,将该进程的状态由S状态改为R状态,并将其重新链接到运行等待队列,等到CPU再次调度该进程时,该进程就可以使用到锁的资源了


总结:

  • 站在操作系统的角度,进程等待某种资源,就是将当前进程的task_struct放入对应的等待队列,这种情况可以称之为当前进程被挂起等待了
  • 站在用户角度,当进程等待某种资源时,用户看到的就是自己的进程卡住不动了,我们一般称之为应用阻塞了
  • 这里所说的资源可以是硬件资源也可以是软件资源,锁本质就是一种软件资源,当我们申请锁时,锁当前可能并没有就绪,可能正在被其他线程所占用,此时当其他线程再来申请锁时,就会被放到这个锁的资源等待队列当中

死锁的四个必要条件

  • 互斥条件: 一个资源每次只能被一个执行流使用
  • 请求与保持条件: 一个执行流因请求资源而阻塞时,对已获得的资源保持不放
  • 不剥夺条件: 一个执行流已获得的资源,在未使用完之前,不能强行剥夺
  • 循环等待条件: 若干执行流之间形成一种头尾相接的循环等待资源的关系

注意: 这是死锁的四个必要条件,也就是说只有同时满足了这四个条件才可能产生死锁


避免死锁的方法

  • 破坏死锁的四个必要条件
  • 加锁顺序一致
  • 避免锁未释放的场景
  • 资源一次性分配

除此之外,还有一些避免死锁的算法,比如死锁检测算法和银行家算法


http://www.ppmy.cn/news/92616.html

相关文章

Mock 测试技术详解及高级特性,你不得不会的技能!

Mock 是软件测试中常用的一种技术&#xff0c;它可以模拟外部依赖的行为和状态&#xff0c;以便进行更全面、准确和可靠的测试覆盖。Java 中的 Mock 框架是一个功能强大、易用的工具&#xff0c;可以帮助开发者快速、轻松地创建和配置 Mock 对象&#xff0c;并支持各种灵活的测…

nestjs笔记

控制反转 IoC 控制反转&#xff08;Inversion of Control&#xff0c;缩写为 IoC&#xff09;是面向对象编程中的一种设计原则&#xff0c;可以用来降低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff09;…

最新的Oracle 数据库Sample Schema安装指南

今天根据之前博客如何使用github安装Oracle 数据库Sample Schema &#xff08;示例Schema&#xff09; &#xff0c;发现居然报错了。 从网站上看了下&#xff0c;发现确实有些变化&#xff0c;现描述如下。 第一个变化是OE和PM两个Schema进入归档状态&#xff0c;目前建议使用…

高校智能用电管理系统的应用探讨

摘 要&#xff1a;随着现代科学技术的发展&#xff0c;在高校中开始广泛应用智能化技术&#xff0c;改善学生宿舍的用电管理模式&#xff0c;提高宿舍的管理水平&#xff0c;有利于实现高校宿舍用电管理的科学化。本文主要阐述传统高校宿舍用电管理模式&#xff0c;设计高校智能…

编译原理实验-词法分析

具体代码已放至Github&#xff08;仅供参考&#xff09;&#xff1a; qxpBlog/Compiler_UESTC: 电子科技大学编译原理实验 (github.com) 具体实验过程如下&#xff1a; 一、实验内容及步骤&#xff1a; 1. 实验内容&#xff1a; 用flex生成一个词法分析器&#xff0c;用以识…

什么是 Spring Boot Actuator?如何在 Spring Boot 中使用 Actuator?

当我们在开发和部署应用程序时&#xff0c;监控应用程序的健康状况和性能是非常重要的。Spring Boot Actuator 为我们提供了一组现成的端点&#xff08;endpoints&#xff09;&#xff0c;可以让我们方便地监控和管理应用程序。在本文中&#xff0c;我们将了解 Spring Boot Act…

【ISO14229_UDS刷写】-1-$34诊断服务RequestDownload理论部分

总目录&#xff1a;&#xff08;单击下方链接皆可跳转至专栏总目录&#xff09; 《UDS/OBD诊断需求编辑工具》总目录https://blog.csdn.net/qfmzhu/article/details/123697014 目录 1 $0x34 RequestDownload诊断服务描述 2 0x34服务请求消息 2.1 0x34服务请求消息定义 2.…

Eclipse教程Ⅲ

Eclipse 菜单 Eclipse 查看的菜单栏通常包含以下几个菜单&#xff1a; File 菜单Edit 菜单Navigate 菜单Search 菜单Project 菜单Run 菜单Window 菜单Help 菜单 通过 Eclipse 插件你可以添加新的菜单和菜单项。 菜单描述 菜单名描述FileFile 菜单运行你打开文件&#xff0c;…