热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

死锁及如何处理死锁-转载

转载自:http:www.andylouse.nethtmlitknowledge201273.html一、什么是死锁死锁定义:多个进程在执行过程中,因争夺同类资源且资源分配不当而

转载自:http://www.andylouse.net/html/itknowledge/2012/73.html

一、什么是死锁

死锁定义:多个进程在执行过程中,因争夺同类资源且资源分配不当而造成的一种互相等待的现象,若无外力作用,它们都将永远无法继续执行,这种状态称为死锁,这些处于等待状态的进程称为死锁进程。

规范定义:集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该集合正处于死锁状态,这组进程也是死锁进程。

比如,进程P1在执行时占用所有的资源R1,此时,进程P1申请资源R2才能继续执行,同时,进程P2占用了所有的资源R2,需要申请资源R1才能继续执行,而双方都需要获得对方的资源后才能释放已占用的资源,这样就形成了一个最简单的循环等待——死锁。

二、产生死锁的原因

在系统提供给多个进程使用的共享资源的数量不够时,这些进程在竞争资源时将会产生死锁。因此,可以说任何多线程的系统都有可能产生死锁,而产生死锁的原因大致分为如下两类:

系统提供的资源不够每个进程使用,进程在竞争资源时产生死锁

首先描述一下系统中的两类资源——可剥夺资源、不可剥夺资源和临时资源。可剥夺资源是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺,如优先级高的进程可以剥夺优先级低的进程的资源;而对不可剥夺资源来说,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等;临时资源是指由一个进程产生,被另一个进程使用,短时间后便无用的资源,也称为消耗性资源,如硬件中断、信号、消息、缓冲区内的消息等。

进程在竞争不可剥夺资源和临时资源时,都有可能引发死锁,这种情况下,必须通过外力的作用,强制其中某些进程释放其所占用的资源,我们常用的方法是撤消进程,详情将在解除死锁中讲解。

系统提供的资源够部分进程使用,但进程推进算法不当引发死锁

进程在运行中具有异步性特征,多个进程可以按不同的顺序向前推进,若进程推进算法合法,则进程申请资源、释放资源的过程非常顺利,否则,一旦让某进程申请到过多的资源却又不能完成任务释放资源,而剩下的资源又不够其他进程申请,这样,就发生了进程死锁。

总结以上原因,我们得出产生死锁有四个必要条件:

互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用,如果此时有其它进程请求资源,则必须等到该进程完成任务并释放资源。

请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

不可剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在完成任务后由自己释放。

环路等待条件:指在发生死锁时,必然存在一个进程-资源的环形链,即进程集合{P0,P1,P2,…,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

三、预防死锁

系统本身提供足够的资源

有n个进程竞争同类资源,每个进程需要p个资源,如果系统能够提供该类资源n(p-1)+1个,就能保证不产生死锁。

使用合理的资源分配方法

通常情况下,系统提供的资源往往不能满足拥挤的进程来使用,所以,我们更多的是使用合理的进程分配方法来预防死锁。

资源独占:让进程独自占用某些资源,进到它任务完成全部释放。

资源顺序分配:按照某种规则将系统中的所有资源进行统一编号,进程在申请资源时必须一次性完全申请它所需要使用的而且属于同一类的所有资源,在申请不同类资源时,必须按各类设备的编号依次申请。

资源受控动态分配:分配资源前先检查会不会发生死锁,这就要求各进程说明所需资源,将资源分类,按不同策略分配,又称为静态说明动态分配。

银行家算法

避免死锁算法中最有代表性的算法是Dijkstra E.W 于1968年提出的银行家算法。该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。这样申请者就可很快完成其计算,然后释放它占用的资源,从而保证了系统中的所有进程都能完成,因此可避免死锁的发生。

小结

理论上,预防死锁不难实现,只需要破坏四个必要条件中的一个或多个即可,但是要破坏他们,往往需要施加严格的限制条件,这样可能会导致系统资源利用率和系统吞吐量降低。

四、发现死锁

检测死锁:当进程进行资源请求时检查并发进程组是否构成资源的请求和占用环路,如果不存在这一环路,则该系统不会产生死锁。

利用简化进程-资源图来检测系统是否产生死锁。所谓化简是指一个进程的所有资源请求均能被满足的话,可以设想:进程得到其所需的全部资源→最终完成任务,并释放所占有的全部资源,这种情况下,则称进程-资源分配图可以被该进程化简,化简方法如下:

(1) 在资源分配图中,找出一个既非等待又非孤立的进程结点Pi,由于Pi可获得它所需要的全部资源,且运行完后西方它所占有的全部资源,故可在资源分配图中消去Pi所有的申请边和分配边,使之成为既无申请边又无分配边的孤立结点。

(2) 将Pi所释放的资源分配给申请它们的进程,即在资源分配图中将这些进程对资源的申请边改为分配边。

(3) 重复(1)、(2)两步骤,直到找不到符合条件的进程结点。

经过化简后,若能消去资源分配图中的所有边,使所有进程都成为孤立结点,则该图是可完全化简的。

死锁定理:系统中某个时刻S为死锁状态的充分必要条件是,S时刻系统的资源分配图是非完全可化简的。

五、解除死锁

一旦检测到死锁,便要立即设法解除死锁,以下是几种解除死锁的方法:

剥夺法:将某些资源从其它进程强占过来分配给另一些进程。

这种方法要求强占资源后不影响原进程恢复后的执行,但是关系到资源的属性,难于实现。

回退法:系统执行过程中设置若干断点,并保存现场,在产生死锁后立即采用回滚方式释放资源以解除死锁。

这种方法要求被保护的现场不能频繁覆盖,同时需要考虑断点的设置时机与空间开销。

撤消进程:从系统中撤消某些进程,释放资源以解除死锁。

这种方法要求保证系统的数据等的一致性,但问题是我们往往难于判断是否能保证其一致性。


推荐阅读
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 本文探讨了在Java多线程环境下,如何确保具有相同key值的线程能够互斥执行并按顺序输出结果。通过优化代码结构和使用线程安全的数据结构,我们解决了线程同步问题,并实现了预期的并发行为。 ... [详细]
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • Linux系统中Java程序Too Many Open Files问题的深入解析与解决方案
    本文详细分析了在Linux环境下运行的Java应用程序中可能出现的“Too many open files”异常现象,探讨其成因及解决方法。该问题通常出现在高并发文件访问或大量网络连接场景下,对系统性能和稳定性有较大影响。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • 机器学习核心概念与技术
    本文系统梳理了机器学习的关键知识点,涵盖模型评估、正则化、线性模型、支持向量机、决策树及集成学习等内容,并深入探讨了各算法的原理和应用场景。 ... [详细]
author-avatar
robinqianqcs521
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有