1. 死锁的概念
各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的状态
比如哲学家进餐问题
饥饿:由于长期得不到想要的资源,某进程无法向前推进的状况,比如短进程优先算法中,只要有短进程到来,长进程就会一直处于饥饿的状态
选择题考察
共同点 | 区别 | |
---|---|---|
死锁 | 都是进程 | 至少有两个以上的进程同时发生死锁 |
饥饿 | 无法顺利 | 可能只有一个进程发生饥饿 |
死循环 | 向前推进 | 死锁和饥饿是操作系统的问题,而死循环是程序运行中的bug |
2.死锁产生的必要条件:
1)互斥条件:只有对必须互斥使用的资源的争抢才会导致死锁(例如哲学家的筷子)
2)不剥夺条件:进程使用的资源不能被强行剥夺(就像一个哲学家在用筷子时不能被另一个哲学家剥夺手里的筷子一样)
3)请求和保持条件:进程保持了一个资源,却又申请一个新的资源,而该资源已经被占有
3)循环等待条件:存在一种进程资源的循环等待链,链中每一个进程所获得的资源又被下一个资源所请求
选择题考点
注意!死锁一定有循环等待,而有循环等待不一定是死锁
3.死锁产生的原因
1)系统资源的竞争,例如哲学家问题中,如果每个哲学家都拿起自己左边的筷子,那么每个哲学家都无法吃饭
2)进程推进顺序非法,请求和释放资源的顺序不当,例如:
3)信号量使用不当也可能产生死锁现象,例如
semaphore mutex=1;
semaphore full=0;
semaphore empty=n;
producer(){
while(1){
produce a series of data; //生产产品
P(empty); //获取一个空闲的缓冲区(第一次写错了)
P(mutex); //与producer进程下的V(mutex)是一对,不能与P(empty)交换位置
add data to buffer; //将生产的产品放入缓冲区
V(mutex);
V(full);
}
}
consumer(){
while(1){
P(full); //获取一个满的缓冲区(第一次写错了)
P(mutex);
remove an item from buffer; //移走缓冲区中的产品
V(mutex);
V(empty); //空闲缓冲区+1
consume the item; //消费产品
}
}
生产者消费者问题中,如果将上述的consumer中P(full)和P(mutex)交换,producer中的P(empty),P(mutex)交换,就会导致:
当empty=0时,生产者进程进行了P(mutex)之后就切换到了消费者进程,而消费者进程就会被一直卡在P(mutex)上,无法进行下一步,而由于empty=0,生产者进程也无法进行下一步,所以发生了死锁
总而言之,一句话,对不可剥夺资源的不合理利用,可导致死锁
4.死锁的处理策略
- 预防死锁:破坏死锁的四个必要条件
- 避免死锁:避免死锁进入不安全的状态(银行家算法)
- 死锁的检验和解除:允许死锁的发生,系统负责检查并解除死锁
1)预防死锁
① 破坏互斥条件
使用spooling技术,使得两个进程认为打印机是共享设备,但实际上两者还是互斥的在工作
②破坏不剥夺条件
方案一:申请资源得不到满足时,立即释放所有的资源
方案二:通过优先级关系强行剥夺资源
③破坏请求和保持条件
使用静态分配的方法,即进程在运行前一次申请完他所需要的全部资源,在它的资源未满足前,不让其投入运行
缺点:可能某些资源只需要用很短的时间,而有些进程需要长期占用这种资源,从而导致系统资源的严重浪费,资源利用率低,也可能导致某些进程饥饿的现象。
④破坏循环等待条件
采用顺序资源分配法:规定每个进程必须按照编号递增的顺序请求资源,同类资源一次性申请完
缺点:
不方便新增设备,用户编程麻烦
2)避免死锁
① 系统安全状态
什么是安全序列?
就是按照这种序列分配资源,每个进程都能顺利的满足。
例如:哲学家进餐问题中先分配资源给奇数号哲学家就是一种安全序列
只要找到一个安全序列,系统就是安全状态,安全序列可能有多个
注意安全序列,不安全状态,和死锁之间的联系:(选择题考点)
如果系统进入安全状态,就一定不会死锁。如果系统进入不安全状态,就有可能发生死锁。
例如:哲学家进餐问题中如果每个哲学家都先拿起自己左边的筷子,但是有一个哲学家先归还了自己手中的筷子,那么他相邻的哲学家就可以拿起筷子吃饭了,随后其他哲学家也可以这样做了,最后就没有再发生死锁了。
②银行家算法
3)死锁的检测与解除
①死锁的检测
②死锁的解除
并不是系统中所有的进程都是死锁状态,用死锁检测算法化简资源分配图后,还连着边的那些进程就是死锁进程。
法一:资源剥夺法,就是破坏不剥夺条件,从而使得优先级高的进程可以剥夺其他进程的资源,从而先完成。
法二:撤销进程法,强制撤销部分,甚至所有死锁进程,这种方法造成的代价很大。
法三:进程回退法,让一个或者多个进程回退到足以避免死锁的地步,这就要求系统记录历史信息点,设置回退点。