Linux 多线程:死锁的理解

时间:2022-01-05 01:10:21

一、死锁的产生

  死锁就是多个进程(线程)因为对临界资源的访问流程不合理而导致程序卡死。

  如图:有两个线程,两个资源。线程A此时占据了1号资源,线程B占据了2号资源,但他们同时又想申请对方手里的资源,如果这时候双方都不肯让步,那就只有一个结果,程序卡死。

Linux 多线程:死锁的理解

 看完死锁的示例,接下来看看产生死锁的四个必要条件:

  1. 互斥条件:一个临界资源在同一时间只能被一个线程使用。(一个厕所同一时间只能被一个人用)
  2. 不可剥夺条件:线程如果正在使用临界资源,那么这个临界资源不可以被其他线程抢夺。
  3. 请求与保持条件:用上图举例,线程A申请了1号资源,然后又去申请2号资源,但就算2号资源申请失败,线程A也不会释放1号资源,而是继续占据。
  4. 循环等待条件:就像上图一样,进程互相申请对方占据的资源。

二、预防死锁

 预防死锁就是要破坏死锁产生的必要条件

  1. 破坏不可剥夺条件:线程如果没有把需要的资源全部申请到,那么就会一直等待。在等待的途中,如果有其他线程要申请等待线程所拥有的资源,等待线程就要让给其他线程。(意思就是,我一直都没申请到我想要的B资源,但是既然你需要我已经申请到的A资源,那我就让给你)
  2. 破坏请求与保持条件:如上图,线程A占据1号资源,去申请2号资源,如果2号资源申请失败,线程A把1号资源也释放。
  3. 破坏循环等待条件:尽量避免上图中的情况,给线程安排一个合理的推进顺序。

三、避免死锁

  预防死锁和避免死锁是不一样的。预防就相当于打了个疫苗,给自己先加上一层保护壳。避免是在日常生活中,我们时刻注意,不要做一些危险的事情导致感染。

  避免死锁的思想就是在进程每次申请资源的时候,都要先模拟分配,看看是否会导致死锁。如果模拟分配不会死锁,才会实际分配资源。代表性的算法是:银行家算法。