计算机系统的一些独占性资源任何时刻都只能被一个进程使用。例如打印机,磁带机等。两个进程同时打开一个文件会使文件系统瘫痪。故需要授权进程排他性的访问某一个资源。
两个针对于相同一个资源进行同时请求的进程,两个进程未释放彼此需要的资源,将造成双方阻塞,进而形成死锁。
资源:
资源可以是硬件设备,也可以是一组信息,为一种任何时候都只能被一个进程使用的任何对象。
资源的分类:
可抢占资源: 可以从拥有它的进程中抢占而不会产生任何副作用,例如存储器。
不可抢占资源:在不引起相关的计算失败的情况下,无法把它从占有它的进程中抢占回来。
对于资源来说一般可抽象为三个步骤:1.资源请求 2.资源操作.3.释放资源,在一些系统中,某个进程在资源请求失败时会返回一个错误信号,请求的进程会等待一段时间然后重试,而另一种系统的进程会处于一种请求资源,睡眠,再请求的循环中,期间并未执行有用的操作,意义基本等同于阻塞。
资源的获取:
进程A
{
获取资源1
获取资源2
操作资源1、2
释放资源2
释放资源1
}
进程B
{
获取资源1
获取资源2
操作资源1、2
释放资源2
释放资源1
}
这种情况,某个进程可能独自占用1、2,另一个进程要想获取资源需要等到另一个资源被释放。
进程A
{
获取资源1
获取资源2
操作资源1、2
释放资源2
释放资源1
}
进程B
{
获取资源2
获取资源1
操作资源1、2
释放资源1
释放资源2
}
这种情况,可能一个进程获取了两个资源并且阻塞了另一个进程,也有可能两个进程分别获取了一种资源而等待另一种资源被释放,进而造成了死锁的发生
死锁的定义:
如果一个进程集合中的每个进程都在等待只能由该组进程中的其他进程才能引发的事件,那么该组进程是死锁的。
死锁的条件:
1.互斥条件 每个资源要么已经分配给了一个进程,要么就是可用的。
2.占有和等待条件 已经得到了某个资源的进程可以再请求新的资源。
3.不可抢占资源 已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
4.环路等待条件 死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路中的每个进程都在等待着下一个进程所占有的资源。
死锁的建模:
上图右侧代表一个死锁,即两个进程都同时占有对方想要的资源,却请求对方已有的资源。两个进程都被阻塞,导致形成死锁。
解决死锁的策略:
1.忽略该问题
2.检测死锁并且恢复
3.仔细对资源进行分配,从而预防死锁的发生
4.破坏死锁的必要条件,防止死锁的发生。
死锁检测:
每种类型一个资源的死锁检测:一种方法是画图明确各种资源和进程之间的请求和持有关系,通过判断最终的图中是否存在
“环”来判断是否存在死锁。
正如图中: 进程D、G、E和资源T、U、v构成了一个“环”,所以他们能够形成死锁。
另外,为了方便我们理应有一个算法来完成死锁的检测工作:
每个类型有多种资源的死锁检测:
此方法定义几个矩阵:
当前已分配矩阵表示某个进程已持有的资源
请求矩阵为进程i请求的资源
现有资源表示所有资源
可用资源表示进程持有之后所剩的可待请求的资源
C11就表示1进程所持有的资源1的数量,R11表示进程1所请求的资源1的数量,依次类推。
现有资源 = 可用资源 + 当前所有进程所分配的资源
例:
在三个进程,四种资源的过程中, 进程1有一台扫描仪,进程2有2台磁带机和1个CD-ROM驱动器,进程三有一个绘图仪和2台扫描仪。
E: 磁带机 绘图仪 扫描仪 CD-ROM驱动器
4 2 3 1
已分配矩阵为 E减去各种资源求和后得到的就为 可用资源 A
C 0 0 1 0
2 0 0 1
0 1 2 0
A 2 1 0 0
判断是否出现死锁则需要看可用资源A能否满足请求矩阵中的进程需求
R 2 0 0 1
1 0 1 0
2 1 0 0
进程1无法满足,因为A中没有CD-ROM驱动器
进程2也无法满足,因为A中没有扫描仪可用
进程2可以满足
进程2执行完成后,释放其所持有的资源和请求得到满足的资源
A= 0120+2100=2220
而后进程2就可以满足,随即进程1也得到了满足,该环境不存在死锁。
死锁恢复:
方法1: 抢占恢复 在不通知原进程的情况下,将某一个资源从一个进程强行取走给另一个进程使用,接着又送回.这种方法到底是否可行,要
看进程所要拥有的资源是否比较容易收回.
方法2: 利用回滚恢复 假设系统设计人员以及主机操作人员了解到死锁可能发生,他们就可以周期性地对进程进行检查点检查
.也就是将进程的状态写入一个文件以备以后重启. 该检查点记录了资源状态,进程占有哪些资源. 一旦检测到死锁,很容易发现需要哪些资源.就从较早的一个检查点开始,这样所需要资源的进程就会回滚到一个时间点.
方法3: 杀死进程恢复 尽可能少的杀死环中的进程从而破坏环. 另外就是牺牲外部一个进程,将其杀死,其释放的资源就可以满足环中某个进程的请求,从而无法形成环.如果可能的话,杀死可以从头开始重新运行而且不会带来副作用的进程.
死锁的避免:
安全状态和不安全状态: