什么是死锁
在并发环境下,各进程因竞争资源而造成的一种互相等待对方手里的资源,导致各进程都阻塞,都无法向前推进的现象
发生死锁后若无外力干涉,这些进程都将无法向前推进
死锁,饥饿,死循环区别
饥饿:由于长时间得不到想要的资源,导致各进程都堵塞
死循环:某进程执行过程中一直跳不出某个循环的现象,有的死循环是逻辑错误,有的是程序员故意的,比如前面生产者消费者问题中的死循环,就是为了阻止其他进程进来
死锁产生的必要条件
其中最后一段的意思就是,如果有同类可替代的资源,就算循环等待也可能不发生死锁,就像图中的老人也有一个筷子,他可以给哲学家3号用
什么时候会发生死锁
总之,对不可剥夺的资源的不合理分配,可能导致死锁
死锁的处理策略
静态策略:预防死锁思想:破坏产生死锁的一个或几个必要条件
- 破坏互斥条件
把只能互斥访问的资源改为允许共享使用,就不会进入死锁状态
比如SPOOLing技术,就是把独占设备在逻辑上改造成共享设备
如图中,实际上只是把进程们传到输出进程,有一种逻辑上共享的感觉,最终打印机还是一个一个打印
缺点:并不是所有资源都可以改造成可共享使用的资源,且为了系统安全,很多地方还需要保护这种互斥性,因此,很多时候无法破坏互斥条件
- 破坏不可剥夺条件
- 破坏请求和保持条件
上图的意思是,如果源源不断的有A类进程和B类进程,那当一个A进程释放后就会马上把资源1分给下一个A进程,B进程同理,只有A,B都不用,C才能用,因此可能造成C进程饥饿
- 破坏循环等待条件
缺点2解释:因为只能先占小的再占大的,所以当我想先用7号,再用5号,就只能先占5号,让他空闲一段时间,7号才能继续,这样就会造成资源浪费
缺点3解释:比如有的机器要先5后7,有的机器要先7后5,你就要改,就很麻烦
动态策略:避免死锁安全序列:指系统如果按这种序列分配资源,则每个自愿都能顺利完成,只要能找出一个安全序列,系统就是安全状态,当然,安全序列可能不止一个
若分配资源后,系统找不到一个安全序列,系统就进入了不安全状态,这就意味着之后可能所有进程都无法顺利进行下去,但如果有进程归还了一些资源,系统也有可能重新回到安全状态,不过在分配资源之前我们要考虑到最坏的情况
如果系统处于安全状态,就一定不会发生死锁,如果系统进入不安全状态,可能发生死锁(处于不安全状态不一定发生了死锁,发生死锁一定是在不安全状态)
因此在分配资源之前预先判断这次分配是否会导致系统进入不安全状态,以此决定是否答应资源分配请求,这也就是银行家算法的核心
银行家算法注意这里的”把该进程加入安全序列,并把该进程持有的资源全部回收”,比如说我还有可用资源(6,3,2),那我把他分配给进程P0,进程P0满足他的最大需求就会把资源都释放出来,我的可用资源就是(6,3,2)+(2,2,1)=(8,5,3)
死锁的检测和解除若系统中不采取预防死锁的措施,也不采取避免死锁的措施,那系统就很有可能出现死锁,在这种情况下系统应提供以下两个算法
死锁检测算法:用于检测系统状态,以确定系统中是否发生了死锁
死锁解除算法:当认定系统中已经发生了死锁,利用该算法可将系统从死锁状态中解脱出来
- 死锁的检测
① 用某种数据结构来保存资源的请求和分配信息
②提供一种算法(依次消除与不阻塞进程相连的边,直到无边可消),利用上述信息来检测系统是否已进入死锁状态
- 进程的解除