1. 死锁的必要条件
- 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
- 占有和等待:已经得到了某个资源的进程可以再请求新的资源。
- 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
- 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
2. 解决死锁的策略
- 鸵鸟策略:把头埋在沙子里,假装根本没发生问题。
因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。
当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略。
大多数操作系统,包括 Unix,Linux 和 Windows,处理死锁问题的办法仅仅是忽略它。- 死锁检测与死锁恢复:
死锁检测:不试图阻止死锁,而是当检测到死锁发生时,采取措施进行恢复。
每种类型一个资源的死锁检测算法是通过检测有向图是否存在环来实现,从一个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示有向图存在环,也就是检测到死锁的发生。
死锁恢复:
1.利用抢占恢复
2.利用回滚恢复
3.通过杀死进程恢复- 死锁预防:在程序运行之前预防发生死锁。
1.破坏互斥条件:例如假脱机打印机技术允许若干个进程同时输出,唯一真正请求物理打印机的进程是打印机守护进程。
2.破坏占有和等待条件:一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。
3.破坏不可抢占条件
4.破坏环路等待:给资源统一编号,进程只能按编号顺序来请求资源。- 死锁避免:在程序运行时避免发生死锁。
安全状态:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一个进程运行完毕,则称该状态是安全的。
3. 写出和分析死锁的代码
4. 说明在数据库管理系统或者 Java 中如何解决死锁。
JAVA:1.调整申请锁的范围。2.调整申请锁的顺序。3.避免死锁的发生: 如果其它对象的这个方法会消耗比较长的时间,那么就会导致锁被我们持有了很长的时间; 如果其它对象的这个方法是一个同步方法,那么就要注意避免发生死锁的可能性了;
数据库:
(1)尽量避免并发地执行涉及到修改数据的语句。
(2)要求每个事务一次就将所有要使用的数据全部加锁,否则就不予执行。
(3)预先规定一个封锁顺序,所有的事务都必须按这个顺序对数据执行封锁。如不同的过程在事务内部对对象的更新执行顺序应尽量保持一致。
(4)每个事务的执行时间不可太长,在业务允许的情况下可以考虑将事务分割成为几个小事务来执行。【比如说把复杂的多表查询分散成多次单表查询】
(5)数据存储空间离散法。数据存储空间离散法是指采取各种手段,将逻辑上在一个表中的数据分散到若干离散的空间上去,以便改善对表的访问性能。主要通过将大表按行或列分解为若干小表,或者按不同的用户群分解两种方法实现。这种方法类似分散“数据热点”,但是确实,如果数据不是太经常被访问,那么死锁就不会太经常发生。
(6)还是类似(1)的,比如有一个修改上百条记录的update语句,我们可以修改成每10条一个update语句,或者干脆就每条记录一个update语句。
(7)将经常更新的数据库和查询数据库分开。
参考:https://blog.csdn.net/lyabc123456/article/details/81060477
网友评论