面试冲刺:49---死锁是怎么产生的?死锁如何预防?如何避免死锁?死锁如何检测?死锁如何解除?

一、死锁产生的原因

  • 下面是死锁产生的必要条件(4个,缺一不可):
    • 互斥:资源不能被共享,只能由一个进程使用
    • 请求与保持:已经得到资源的进程可以再次申请新的资源
    • 不可剥夺:已经分配的资源不能从相应的进程中被强制地剥夺
    • 循环等待:系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源

面试冲刺:49---死锁是怎么产生的?死锁如何预防?如何避免死锁?死锁如何检测?死锁如何解除?

二、死锁预防

  • 破坏互斥条件:就是在系统里取消互斥、若资源一般不被一个进程独占使用,那么死锁是肯定不会发生的,但一般“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他三个必要条件,而不去涉及破坏“互斥”条件  
  • 破坏请求与保持条件:
    • 方法1:所有的进程在开始运行之前,必须一次性的申请其在整个运行过程各种所需要的全部资源
      • 优点:简单易实施且安全
      • 缺点:因为某项资源不满足,进程无法启动,而其他已经满足了的资源也不会得到利用,严重降低了资源的利用率,造成资源浪费
    • 方法2:该方法是对第一种方法的改进,允许进程只获得运行初期需要的资源,便开始运行,在运行过程中逐步释放掉分配到,已经使用完毕的资源,然后再去请求新的资源。这样的话资源的利用率会得到提高,也会减少进程的饥饿问题
  • 破坏非剥夺条件:当一个已经持有了一些资源的进程在提出新的资源请求没有得到满足时,它必须释放已经保持的所有资源,待以后需要使用的时候再重新申请。这就意味着进程已占有的资源会被短暂的释放或者说被抢占了
  • 破坏循环等待条件:
    • 可以通过定义资源类型的线性顺序来预防,可以将每个资源编号,当一个进程占有编号为i的资源时,那么它下一次申请资源只能申请编号大于i的资源(如下图)
    • 这样虽然避免了循环等待,但是这种方法是比较低效的,资源的执行速度会变慢,并且可能在没有必要的情况下拒绝资源的访问,比如说,线程c想要申请资源1,如果资源1并没有被其他进程占有,此时将它分配给线程c是没有问题的,但是为了避免产生循环等待,该申请会被拒绝,这样就降低了资源的利用率

面试冲刺:49---死锁是怎么产生的?死锁如何预防?如何避免死锁?死锁如何检测?死锁如何解除?

三、死锁避免

  • 避免是指进程在每次申请资源时判断这些操作是否安全
  • 典型算法是“银行家算法”,但这种算法会增加系统的开销

四、死锁的检测

  • 资源分配图不可完全简化,则是死锁状态

五、死锁解除

  • 与死锁检测结合使用,它使用的方式就是剥夺,即将资源强行分配给别的进程
  • 或者终止死锁进程