13.5.2 什么是进程的死锁和饥饿
进程的死锁和饥饿在本章中没有讲述,主要是考虑到它涉及的线程知识会比较复杂。此处将简单地介绍一下它们的基本概念,有兴趣的读者可以自行查阅其他资料。
什么是饥饿?饥饿是由于别的并发进程的激活,而导致持久占有所需资源。饥饿是一个异步过程,预测的时间内不能被激活,最常遇到的线程的两个缺陷是死锁和饥饿。
当一个或多个进程,在一个给定的任务中,协同作用、互相干涉,而导致一个或者更多进程永远等待下去,死锁就发生了。
与此类似,当一个进程永久性地占有资源,使得其他进程得不到该资源时,就发生了饥饿。
首先看死锁问题。考虑一个简单的例子,假如到ATM机上取钱,但是却看到如下的信息“现在没有现金,请稍等再试”,若需要钱,就等了一会儿再试,但是又看到同样的信息。与此同时,一辆运款装甲车正等待着把钱放进ATM中,但是运款装甲车到不了ATM取款机,因为前面的汽车挡着道。客户只有取到钱,才会离开原地。这种情况下,就发生了死锁。在饥饿的情形下,系统不处于死锁状态中,因为有一个进程仍在处理之中,只是其他进程永远得不到执行的机会。
在什么样的环境下,会导致饥饿的发生,这没有预先设计好的规则,而一旦发生下面四种情况之一,就会导致死锁的发生。
❑相互排斥:一个线程或者进程永远占有共享资源,例如,独占该资源。
❑循环等待:进程A等待进程B,而后者又在等待进程C,而进程C又在等待进程A。
❑部分分配:资源被部分分配,例如,进程A和B都需要访问一个文件,并且都要用到打印机,进程A获得了文件资源,进程B获得了打印机资源,但是两个进程不能获得全部的资源。
❑缺少优先权:一个进程访问了某个资源,但是一直不释放该资源,即使该进程处于阻塞状态。
如果上面4种情形都不出现,系统就不会发生死锁。当其中一个进程判断出,它得不到所需要的第2个资源,就释放已经得到的第1个资源,那么第2个进程就可以获得两个资源,并能运行下去。