操作系统自学(十六)死锁以及预防死锁

死锁

在这里插入图片描述

死锁,饥饿,死循环

死锁:各个进程之间互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象
举个例子
比如哲学家进餐问题中,如果每个哲学家手中都拿一支筷子 他们会互相等待对方放下筷子 自己使用
这是就进入了死锁的状态 如果没有外界干预或者是操作系统的干预 他们会一直阻塞下去

再举个例子,假如两个人都想去厕所 他俩也不认识
然后他俩同时跨进厕所的门 他俩还都爱钻牛角尖
于是就互不相让 都在等着对方让步 所以他俩就一直僵持着
这时要是没有一个“智者”调解他俩 他俩就一直僵持下去。

饥饿由于长期得不到想要的资源 某进程无法向前推进的现象
比如短进程优先(SPF)算法中如果有源源不断的短进程进入,则长进程将会一直得不到处理机,从而导致饥饿

死循环某进程执行过程中一直跳不出某个循环的现象,有时是因为逻辑BUG导致的,有时是程序员故意设计的

上述的死循环 必须处于运行态

死锁产生的必要条件

产生死锁必须同时满足一下四大条件:
互斥条件只有对必须互斥使用的资源的争抢才会导致死锁(哲学家问题中的筷子,打印机等等)
内存,扬声器这类可以同时让多个进程同时使用的资源是不会导致死锁的(进程不用阻塞等待这种资源)

不剥夺条件进程所获得的资源在未使用完之前,不能由其他进程强制夺走,只能主动释放

请求保持条件进程已经保持了至少一个资源,但是又提出了新的资源请求,而该资源又被其他进程占有
,此时请求进程被阻塞 ,但是自己的资源有保持不放

循环等待条件存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所求

发生死锁一定有循环等待,但是发生循环等待不一定有死锁

如果同类资源数大于1 则及时有循环等待也未必发生死锁
如果系统资源中每类资源只有一个,那么循环等待就是死锁的充分必要条件

什么时候会发生死锁

1.对系统该资源的竞争,各进程对不可剥夺的资源(打印机等)的竞争可能引起死锁 ,对可剥夺的资源(CPU)的竞争
是不会发生死锁的
2.进程推进顺序非法,请求和释放资源的顺序不当也会导致死锁
例如并发进程P1,P2分别申请并占有了资源R1,R2,之后紧接着P1又申请资源R2,P2也申请R1
两者都会因为申请的资源被对方占有而阻塞,从而发生死锁
3.信号量的使用不当也会造成死锁,例如生产者消费者问题中的互斥的操作放在同步的操作之前,就可能导致死锁

对于不可剥夺的资源分配不合理 就会导致死锁

死锁问题的处理策略

1.预防死锁 破坏死锁产生的四个必要条件
2.避免死锁 避免系统进入不安全的状态(银行家算法 后边会介绍到)
3.死锁的检测和解除 允许死锁发生 系统负责检测出死锁并解除

预防死锁

破坏互斥条件

互斥条件只有对必须互斥使用的资源的争抢才会导致死锁

如果把只能互斥使用的资源改造为允许共享使用,则系统不会进入死锁状态
比如SPOOLing技术操作系统可以使用SPOOLing技术把独占设备在逻辑上改造成共享设备
比如SPOOLing技术把打印机改造成共享设备
在这里插入图片描述
但是并不是所有的资源都可以改造成可共享使用的资源,并且为了系统安全,很多地方还必须保护这种互斥性
因此很多时候无法破坏互斥条件

破坏不剥夺条件

不剥夺条件:进程所获得的资源在未使用完之前,不能由其他进程强制夺走,只能主动释放

方案一:当某个进程请求信的资源得不到满足的时候,他必须立刻释放保持的所有资源,待之后需要时再次重新申请
即使某些资源尚未使用完,也需要主动释放,从而破坏了不可剥夺条件

方案二:当某个进程需要的资源被其他进程所占有的时候,可以由操作系统协助,将想要的资源强行剥夺,这种方式一般需要考虑
各个进程之间的优先级(剥夺调度方式,将处理机强制剥夺给更高优先级的进程使用)但是会发生前功尽弃

为了方便理解 举个例子
假设一个银行有钻石会员和黄金会员 钻石会员比黄金会员的优先级要高
一天黄金会员先到银行 此时银行有1000万的现金 黄金会员需要取300万
随后钻石会员到达银行 钻石会员需要800万 显然银行的钱不够 所以银行先给了钻石会员剩下的700万 然后阻塞了
如果按照方案1 不考虑优先级 那么直接收回钻石会员的700万 等待之后的再次申请
方案2考虑优先级 收回给黄金会员的300万 全部给钻石会员 之后再看黄金会员

该方法的缺点
1.实现起来复杂
2.释放已获得的资源,会导致之前一阶段的工作实效,这种方法适合于以保存和恢复状态的资源
3.反复申请和释放资源增加系统开销,降低系统吞吐量
4.若采用方案1 意味着暂时得不到那个资源,之前获得的资源都要放弃,如果一直发生这样的情况 容易发生饥饿

破坏请求保持条件

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

可以采用静态资源分配方法,在运行前一次申请完它所有的需要的资源,在它的资源未满足之前,不让它投入运行
一旦投入运行之后,资源就一直归他所有,该进程不会请求其他任何资源

缺点
有些资源仅仅需要很短的时间,因此如果进程整个运行器件都要一直保持所有的资源,会造成资源的严重的浪费
资源利用率极低 该方法也可能导致某些进程饥饿

在这里插入图片描述
比如上图中的C类进程就极容易饥饿

破坏循环等待条件

循环等待条件存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被下一个资源所请求

可采用顺序资源分配法 首先给系统中的资源编号 规定每个进程必须按编号递增的顺序请求资源
同类资源一次性申请完

一个进程只有已占有小编号资源的时候,才有资格申请更大的资源,按此规则,已持有大编号的资源,不能逆向申请小编号资源
从而不会发生循环等待的现象

缺点:不方便增加新的设备,因为可能需要重新分配所有的编号
进程实际使用资源的顺序可能和编号的递增顺序不一致 导致资源浪费
必须按照规定次序申请资源,用户编程麻烦。

本来准备这一篇博文 把所有的死锁相关内容写完 但是篇幅太长了
下一篇博客写避免死锁和检测和解除
希望我写的对大家有帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值