一、死锁的产生
死锁就是多个进程(线程)因为对临界资源的访问流程不合理而导致程序卡死。
如图:有两个线程,两个资源。线程A此时占据了1号资源,线程B占据了2号资源,但他们同时又想申请对方手里的资源,如果这时候双方都不肯让步,那就只有一个结果,程序卡死。
看完死锁的示例,接下来看看产生死锁的四个必要条件:
- 互斥条件:一个临界资源在同一时间只能被一个线程使用。(一个厕所同一时间只能被一个人用)
- 不可剥夺条件:线程如果正在使用临界资源,那么这个临界资源不可以被其他线程抢夺。
- 请求与保持条件:用上图举例,线程A申请了1号资源,然后又去申请2号资源,但就算2号资源申请失败,线程A也不会释放1号资源,而是继续占据。
- 循环等待条件:就像上图一样,进程互相申请对方占据的资源。
二、预防死锁
预防死锁就是要破坏死锁产生的必要条件。
- 破坏不可剥夺条件:线程如果没有把需要的资源全部申请到,那么就会一直等待。在等待的途中,如果有其他线程要申请等待线程所拥有的资源,等待线程就要让给其他线程。(意思就是,我一直都没申请到我想要的B资源,但是既然你需要我已经申请到的A资源,那我就让给你)
- 破坏请求与保持条件:如上图,线程A占据1号资源,去申请2号资源,如果2号资源申请失败,线程A把1号资源也释放。
- 破坏循环等待条件:尽量避免上图中的情况,给线程安排一个合理的推进顺序。
三、避免死锁
预防死锁和避免死锁是不一样的。预防就相当于打了个疫苗,给自己先加上一层保护壳。避免是在日常生活中,我们时刻注意,不要做一些危险的事情导致感染。
避免死锁的思想就是在进程每次申请资源的时候,都要先模拟分配,看看是否会导致死锁。如果模拟分配不会死锁,才会实际分配资源。代表性的算法是:银行家算法。