内容 | 所占百分比 |
---|---|
死锁概念 | %30 |
资源 | %25 |
死锁模型 | %5 |
处理死锁的四种策略 | %40 |
死锁的概念
死锁是进程死锁的简称,是由Dijkstra于1965年研究银行家算法时首先提出来的。它是计算机操作系统乃至并发程序设计中最难处理的问题之一。实际上,死锁问题不仅在计算机系统中存在,在我们日常生活中它也广泛存在。
什么是死锁
我们先看看这样一个生活中的例子:在一条河上有一座桥,桥面较窄,只能容纳一辆汽车通过,无法让两辆汽车并行。如果有两辆汽车A和B分别由桥的两端驶上该桥,则对于A车来说,它走过桥面左面的一段路(即占有了桥的一部分资源),要想过桥还须等待B车让出右边的桥面,此时A车不能前进;对于B车来说,它走过桥面右边的一段路(即占有了桥的一部分资源),要想过桥还须等待A车让出左边的桥面,此时B车也不能前进。两边的车都不倒车,结果造成互相等待对方让出桥面,但是谁也不让路,就会无休止地等下去。这种现象就是死锁。如果把汽车比做进程,桥面作为资源,那麽上述问题就描述为:进程A占有资源R1,等待进程B占有的资源Rr;进程B占有资源Rr,等待进程A占有的资源R1。而且资源R1和Rr只允许一个进程占用,即:不允许两个进程同时占用。结果,两个进程都不能继续执行,若不采取其它措施,这种循环等待状况会无限期持续下去,就发生了进程死锁。
在计算机系统中,涉及软件,硬件资源都可能发生死锁。例如:系统中只有一台CD-ROM驱动器和一台打印机,某一个进程占有了CD-ROM驱动器,又申请打印机;另一进程占有了打印机,还申请CD-ROM。结果,两个进程都被阻塞,永远也不能自行解除。
所谓死锁,是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面。很显然,如果没有外力的作用,那麽死锁涉及到的各个进程都将永远处于封锁状态。从上面的例子可以看出,计算机系统产生死锁的根本原因就是资源有限且操作不当。即:一种原因是系统提供的资源太少了,远不能满足并发进程对资源的需求。这种竞争资源引起的死锁是我们要讨论的核心。例如:消息是一种临时性资源。某一时刻,进程A等待进程B发来的消息,进程B等待进程C发来的消息,而进程C又等待进程A发来的消息。消息未到,A,B,C三个进程均无法向前推进,也会发生进程通信上的死锁。另一种原因是由于进程推进顺序不合适引发的死锁。资源少也未必一定产生死锁。就如同两个人过独木桥,如果两个人都要先过,在独木桥上僵持不肯后退,必然会应竞争资源产生死锁;但是,如果两个人上桥前先看一看有无对方的人在桥上,当无对方的人在桥上时自己才上桥,那麽问题就解决了。所以,如果程序设计得不合理,造成进程推进的顺序不当,也会出现死锁。
资源
资源的概念
大部分死锁都与资源有关,所以我们首先来看看资源是什么。
在进程对设备和文件取得了排他性访问权时,为了尽可能的使关于死锁的讨论通用,我们把这种排他性使用对象叫做资源。
资源可以是硬件设备(如驱动)或是一组信息(如数据库中一个加锁的记录)。
计算机中有多种可获得的资源,一些资源会有若干个相同的实例。如蓝光驱动器可以有多个,当某一资源有若干实例时,其中任何一个都可以满足对资源的请求。
简单来说,资源就是随着时间的推移,必须能获得,使用以及释放的任何东西。
资源的分类
可抢占资源: 可以从拥有他的进程中抢过来并不会产生任何副作用,存储器就是一种可抢占资源。
不可抢占资源:是指在不引起相关计算的情况下,无法把他从占有的进程中抢占过来。就跟你不能从别人手中抢走别人的钱一个道理。
某个资源是否可抢占,取决于上下文环境,在一台标准的PC机中,内存的页面总是可以被置换到磁盘中并置换回来的,所以内存是可抢占的。
死锁与不可抢占资源有关。有关可抢占资源的潜在死锁通常可以通过在进程之间重新分配资源而解决,所以,我们的重点放在不可抢占资源上。
使用一个资源所需要的顺序可以用抽象的形式表示如下:
1.请求资源
2.使用资源
3.释放资源
若请求资源不可用,则请求进程被迫被挂起等待。在操一些作系统中,资源请求失败,进程会被阻塞式等待(就等到资源释放为止,期间啥也不做),在资源可用时在唤醒它。
在其他操作系统中,资源请求失败会返回一个错误码,等待一段时间,然后再重新请求。当一个进程请求失败时,他就会陷入这样一个小循环里:请求资源,休眠,再请求。这个时间虽然没有被阻塞,但是,他也不能做任何有价值的工作,实际和阻塞状态一样。
资源的获取以及引发的问题
信号量获取方式
对于像数据库系统记录这类资源,应该有用户去管理其使用,
一种是为每个资源配置一个信号量,这个信号量被初始化为1。互斥信号量也能起到相同的作用。申请资源成功,对信号量减一操作,释放资源就对信号量执行加一操作。信号量来表示资源的多少
有时候,进程需要更多的资源,则他们可以按照顺序获得资源,如果是需要连续两个资源,通常是连续获取。
当只有一个进程执行时,所有的工作都能很好的完成。也就不用考虑资源竞争问题,更不用考虑死锁问题了。
现在考虑两个进程A,B以及两个资源R1,R2的情况。
当两个进程以相同的方式请求资源:先获取资源R1,再获取资源R2。
A进程先于B进程获取资源,当A进程能够成功获得R2并完成他的任务。如果B进程想在第一个进程被释放之前获取该资源,那么他就会由于资源加锁而被阻塞,直到A进程释放资源为止。这种情况会导致阻塞。如下图a编码所示
但是,如果A进程获得资源R1,B进程获得资源R2,现在A进程完成任务需要资源R2,同样B进程需要资源R1。每个进程都抱着自己的资源却想要获得对方的资源,就像吃着碗里瞧着锅里的一样。那么,A,B两进程都无法继续运行,这种情况就会导致死锁。如下图编码b所示
在这里我们看到,编码风格的不同(那种资源先获取)造成了可以执行的程序和不可执行的并且无法检测错误的程序之间的差别
死锁模型
用绿色方框图代表资源,红色椭圆代表进程
资源节点到进程的有向箭头,表示该资源已被请求,授权并被进程占用,如下图a
进程节点到资源节点的有向箭头表示进程请求资源。并且该进程已被阻塞,处于等待该资源的状态,图下图b
在下图c中说明进入了死锁状态:进程A等待着资源1,而资源1被进程B占用着,进程B又在请求资源2,而资源2却被进程A占用着。这样两个进程都必须等待下去。这就构成了死锁的简单模型
处理死锁的四种策略
1)忽略。也许你忽略它,他也会忽略你。
2)检测死锁并恢复。让死锁发生,检测他是否发生,一旦发生死锁,采取行动解决问题
3)仔细对资源进行分配,动态避免死锁
4)破坏引起死锁的四个必要条件之一,防止死锁的产生。
在下一篇博客来介绍死锁的处理方法(链接如下)
https://blog.csdn.net/zgege/article/details/80094813#0-qzone-1-89401-d020d2d2a4e8d1a374a433f596ad1440