【操作系统】如何排查死锁?

news2024/11/26 14:52:40

【操作系统】如何排查死锁?

文章目录

  • 【操作系统】如何排查死锁?
    • 死锁的概念
    • 死锁的排查工具
      • 排查工具 1:jstack
      • 排查工具 2:jconsole
    • 死锁的发生条件
      • 互斥条件
      • 持有并等待条件
      • 不可剥夺条件
      • 环路等待条件
    • 避免死锁问题的发生
    • 总结

死锁的概念

死锁(Dead Lock)指的是两个或两个以上的运算单元(进程、线程或协程),都在等待对方释放资源,但没有一方提起释放资源,从而造成了一种阻塞的现象就称为死锁。

比如线程 1 拥有了锁 A 的情况下试图获取锁 B,而线程 2 又在拥有了锁 B 的情况下试图获取锁 A,这样双方就进入相互阻塞等待的情况,如下图所示:

image-20230306134138304

死锁的代码实现如下:

/**
 * @description: 死锁
 * @author: blblccc
 * @date: 2023/3/6 13:41
 */
public class DeadLockTest {
    public static Object A = new Object();
    public static Object B = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            synchronized (A) {
                try {
                    System.out.println("线程1 抢占A");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (B) {
                    System.out.println("线程1 抢占B");
                }
            }
        }).start();

        new Thread(() -> {
            synchronized (B) {
                try {
                    System.out.println("线程2 抢占B");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (A) {
                    System.out.println("线程2 抢占A");

                }
            }
        }).start();
    }
}

以上程序的执行结果如下图所示:

image-20230306134301153

从上述结果可以看出,线程 1 和线程 2 都在等待对方释放锁,这样就造成了死锁问题。 哪死锁应该如何排查呢?

死锁的排查工具

排查工具 1:jstack

在使用 jstack 之前,先要通过 jps 得到运行程序的进程 ID,使用方法如下:

image-20230306134331349

“jps -l”可以查询本机所有的 Java 程序,jps(Java Virtual Machine Process Status Tool)是 Java 提供的一个显示当前所有 Java 进程 pid 的命令,适合在 linux/unix/windows 平台上简单查看当前 Java 进程的一些简单情况,“-l”用于输出进程 pid 和运行程序完整路径名(包名和类名)。

有了进程 ID(PID)之后,我们就可以使用“jstack -l PID”来发现死锁问题了,如下图所示:

image-20230306134413119

jstack 用于生成 Java 虚拟机当前时刻的线程快照,“-l”表示长列表(long),打印关于锁的附加信息。

排查工具 2:jconsole

使用 jconsole 需要打开 JDK 的 bin 目录,找到 jconsole 并双击打开,如下图所示:

image-20230306134436609

然后选择要调试的程序,如下图所示:

image-20230306134452091

之后点击连接进入,选择“不安全的连接”进入监控主页,如下图所示:

image-20230306134505986

之后切换到“线程”模块,点击“检测死锁”按钮,如下图所示:

image-20230306134518790

之后稍等片刻就会检测出死锁的相关信息,如下图所示:

image-20230306134530534

死锁的发生条件

互斥条件

互斥条件是指多个线程不能同时使用同一个资源

比如下图,如果线程 A 已经持有的资源,不能再同时被线程 B 持有,如果线程 B 请求获取线程 A 已经占用的资源,那线程 B 只能等待,直到线程 A 释放了资源。

img

持有并等待条件

持有并等待条件是指,当线程 A 已经持有了资源 1,又想申请资源 2,而资源 2 已经被线程 C 持有了,所以线程 A 就会处于等待状态,但是线程 A 在等待资源 2 的同时并不会释放自己已经持有的资源 1

img

不可剥夺条件

不可剥夺条件是指,当线程已经持有了资源 ,在自己使用完之前不能被其他线程获取,线程 B 如果也想使用此资源,则只能在线程 A 使用完并释放后才能获取。

img

环路等待条件

环路等待条件指的是,在死锁发生的时候,两个线程获取资源的顺序构成了环形链

比如,线程 A 已经持有资源 2,而想请求资源 1, 线程 B 已经获取了资源 1,而想请求资源 2,这就形成资源请求等待的环形图。

img

避免死锁问题的发生

前面我们提到,产生死锁的四个必要条件是:互斥条件、持有并等待条件、不可剥夺条件、环路等待条件。

那么避免死锁问题就只需要破环其中一个条件就可以,最常见的并且可行的就是使用资源有序分配法,来破环环路等待条件

那什么是资源有序分配法呢?

线程 A 和 线程 B 获取资源的顺序要一样,当线程 A 是先尝试获取资源 A,然后尝试获取资源 B 的时候,线程 B 同样也是先尝试获取资源 A,然后尝试获取资源 B。也就是说,线程 A 和 线程 B 总是以相同的顺序申请自己想要的资源。

我们使用资源有序分配法的方式来修改前面发生死锁的代码,我们可以不改动线程 A 的代码。

我们先要清楚线程 A 获取资源的顺序,它是先获取互斥锁 A,然后获取互斥锁 B。

所以我们只需将线程 B 改成以相同顺序的获取资源,就可以打破死锁了。

img

总结

简单来说,死锁问题的产生是由两个或者以上线程并行执行的时候,争夺资源而互相等待造成的。

死锁只有同时满足互斥、持有并等待、不可剥夺、环路等待这四个条件的时候才会发生。

所以要避免死锁问题,就是要破坏其中一个条件即可,最常用的方法就是使用资源有序分配法来破坏环路等待条件。

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

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

相关文章

TCP、UDP

TCP和UDPTCP报头三次握手,四次挥手确认机制(重传ARQ)重传机制拥塞控制(慢开始-拥塞避免,快重传、快恢复)流量控制(滑动窗口)差错控制(校验和)UDP报头TCP和UDP…

Qt之高仿QQ系统设置界面

QQ或360安全卫士的设置界面都是非常有特点的,所有的配置项都在一个垂直的ScrollArea中,但是又能通过左侧的导航栏点击定位。这样做的好处是既方便查看指定配置项,又方便查看所有配置项。 一.效果 下面左边是当前最新版QQ的系统设置界面,右边是我的高仿版本,几乎一毛一样…

JVM初步理解浅析

一、JVM的位置 JVM的位置 JVM在操作系统的上一层,是运行在操作系统上的。JRE是运行环境,而JVM是包含在JRE中 二、JVM体系结构 垃圾回收主要在方法区和堆,所以”JVM调优“大部分也是发生在方法区和堆中 可以说调优就是发生在堆中&#xf…

国外seo比较好的优化方法有哪些?

随着互联网的不断发展,SEO(搜索引擎优化)变得越来越重要。 对于国外市场,Google搜索引擎是最为重要的搜索引擎之一, 因此在优化国外网站时,需要将Google SEO优化作为首要任务。 关键词研究和优化 在进行…

Windows逆向安全(一)C与汇编的关系

前言 逆向是一种新型的思维模式也是软件开发领域中极为重要的技术,涵盖各种维度去深挖软件架构的本质和操作系统原理,学习逆向后可以在各领域中发挥至关重要的作用,其中包括黑灰色,安全开发,客户端安全,物…

没有对象感,沟通太费劲

沟通中最重要的感觉:对象感! 要沟通的是谁?以啥方式最好? 趣讲大白话:蹲着跟小孩说话 【趣讲信息科技100期】 ******************************* 对象感是沟通者必须训练和提升的 是换位思考的一种能力 以便跟沟通对象进…

【虚拟工厂】SCL编写<机械手加盖模块>应用

使用scl来编写实虚拟工场中的一个机械手加盖应用项目 文章目录 目录 文章目录 前言 1.机械手加盖场景 2.了解各部分功能 3.命名变量找出输入输出 4.在博图建立变量 二、编写思路 1.分析 2.使用小模块化来编写 3.确定编程思路 三、编程 1.上料部分 2.机械手部分 3…

【数据结构】线性表和顺序表

Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线…

新C++(14):移动语义与右值引用

当你在学习语言的时候,是否经常听到过一种说法,""左边的叫做左值,""右边的叫做右值。这句话对吗?从某种意义上来说,这句话只是说对了一部分。---前言一、什么是左右值?通常认为:左值是一个表示数据的表达式(…

Git版本控制管理

Git日志记录查看日志获取执行过的命令查看每一次提交记录比较文件差异还原文件git远程仓库克隆远程仓库移除无效的远程仓库Git远程仓库推送、抓送,和拉取Git远程仓库多人协作冲突问题Git远程仓库SSH协议推送Git分支查看分支创建分支修改分支切换分支推送至远程仓库分…

Python3实现“美颜”功能

导语利用Python实现美颜。。。这是之前在GitHub上下载的一个项目。。。似乎有些日子了。。。所以暂时找不到原项目的链接了。。。今天抽空看了下它源代码的主要思想,似乎挺简单的。。。于是决定用Python3自己复现一下。。。T_T感觉还是挺有趣的。。。Just have a tr…

源码分析Spring @Configuration注解如何巧夺天空,偷梁换柱。

前言 回想起五年前的一次面试,面试官问Configuration注解和Component注解有什么区别?记得当时的回答是: 相同点:Configuration注解继承于Component注解,都可以用来通过ClassPathBeanDefinitionScanner装载Spring bean…

IT服务发布管理过程文件

目的 规范发布管理的提交、审批、沟通、测试、回滚、实施等活动。 范围 适用于我公司的IT服务管理重大变更的内、外部发布。 术语定义 发布:将一个或多个变更交付、分发到实际运行环境中并可对其进行追溯。非项目的IT服务重大变更需要遵循本过程进行发布。发布主要包…

论文投稿指南——中文核心期刊推荐(工业经济)

【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…

使用TorchGeo进行地理空间深度学习

前言TorchGeo是一个PyTorch域库,提供特定于地理空间数据的数据集、采样器、转换和预训练模型。https://github.com/microsoft/torchgeo几十年来,地球观测卫星、飞机和最近的无人机平台一直在收集越来越多的地球表面图像。有了关于季节和长期趋势的信息&a…

【算法】算法基础入门详解:轻松理解和运用基础算法

😀大家好,我是白晨,一个不是很能熬夜😫,但是也想日更的人✈。如果喜欢这篇文章,点个赞👍,关注一下👀白晨吧!你的支持就是我最大的动力!&#x1f4…

查找Pycharm跑代码下载模型存放位置以及有关模型下载小技巧(model_name_or_path参数)

目录一、前言二、发现问题三、删除这些模型方法一:直接删除注意方法二:代码删除一、前言 当服务器连不上,只能在本地跑代码时需要使用***预训练语言模型进行处理 免不了需要把模型下载到本地 时间一长就会发现C盘容量不够 二、发现问题 正…

c++11 标准模板(STL)(std::unordered_map)(九)

定义于头文件 <unordered_map> template< class Key, class T, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator< std::pair<const Key, T> > > class unordered…

Python进阶-----高阶函数zip() 函数

目录 前言&#xff1a; zip() 函数简介 运作过程&#xff1a; 应用实例 1.有序序列结合 2.无序序列结合 3.长度不统一的情况 前言&#xff1a; 家人们&#xff0c;看到标题应该都不陌生了吧&#xff0c;我们都知道压缩包文件的后缀就是zip的&#xff0c;当然还有r…

Mybatis源码分析系列之第四篇:Mybatis中代理设计模型源码详解

一&#xff1a; 前言 我们尝试在前几篇文章的内容中串联起来&#xff0c;防止各位不知所云。 1&#xff1a;背景 我们基于Mybatis作为后台Orm框架进行编码的时候&#xff0c;有两种方式。 //编码方式1 UserDao userDao sqlSession.getMapper(UserDao.class); userDao.quer…