在浅析线程的同步互斥的博客中提到死锁问题。
那么什么是死锁呢?
死锁的概念
在某一个程序当中,由于一些原因,导致某一个进程或者线程无限期的占有一种或多种公共资源不归还。导致其他进程或者是线程将永远获取不到这些公共资源,而进程或线程选择进行挂起等待公共资源,进而导致这些线程或进程的饥饿问题。这就是死锁问题。
形成死锁的四个必要条件
- 互斥使用资源
- 占有和等待资源
- 不可抢夺资源
- 循环等待资源
我们一个一个来说这四个条件,首先如果没有互斥使用资源的话,所有进程或线程都可以随意的使用公共资源,所以不存在长期占有不归还。再者,如果线程或进程再申请到一部分公共资源的时候,它还需要其它的资源,或是等待某些条件,那么这个时候就会发生阻塞等待,直至条件完成,那么这个过程中就会造成其它进程的死锁问题。如果能够抢占资源,倘若是优先级较低的长期占有公共资源,优先级高的能忍?二话不说直接就是抢,还敢长期占有?最后一个循环等待,如果不循环等待,进程或者线程去申请公共资源,发现被别人用着,那直接去做别的事情,不进行等待,不会影响进程线程进度,大不了就是错误终止。这样也不会有死锁问题。
如何处理死锁问题?
对死锁问题的处理不仅仅只从出现死锁问题开始。首先我们应该要预防死锁问题的出现,再者我们应该避免会发生死锁的可能,最后在发生死锁时,我们应该及时检测,并解决死锁问题。
预防
我们在分配资源的时候,首先应该规定一些资源分配的方式方法,申请资源的时候按照所预定的规程来申请,同时系统也按照预定的方式方法进行分配。这些分配的方式,目的就是使产生死锁的四个必要条件中任意一个条件不成立即可,这样系统就不会发生死锁问题。
避免
在避免死锁问题的时候,其实常常采用两种方法:
- 若一个进程的请求会导致死锁,则不启动该进程。
- 若一个进程增加的资源请求会导致死锁,则不允许这一资源分配。
所在避免的实质相当于提前预料到了某些动作执行完毕后发生死锁问题,那么就拒绝执行造成死锁问题的动作。
这里常用的算法就是银行家算法:银行家算法的实现
银行家算法实现的思想:
允许进程动态地申请资源,系统在每次实施资源分配之前,先计算资源分配的安全性,若此次资源分配安全(即资源分配后,系统能按某种顺序来为每个进程分配其所需的资源,直至最大需求,使每个进程都可以顺利地完成),便将资源分配给进程,否则不分配资源,让进程等待。
检测与解决
操作系统允许死锁的发生,但是操作系统会不断监视系统的进展情况,判断死锁是否真的发生,一旦死锁真的发生则采取专门的措施,解除死锁并以最小的代价恢复操作系统的运行。
在发生死锁问题后,我们处理方法有,首先取消掉所有可能造成死锁的进程或线程。接着逐一打开, 直至发生死锁,找到最终造成死锁问题的进程或线程。找到之后,对其进行处理,使得上述四个必要条件某一个不成立即可。
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!