死锁是操作系统中的一个关键问题,在面试中经常会被问到,下面将从死锁的概念,产生死锁的必要条件,以及如何预防死锁,避免死锁和检测死锁几个方面对死锁进行说明。

死锁的概念

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态。通俗的讲,就是两个或多个进程无限期的阻塞、相互等待的一种状态。

 

死锁产生的四个必要条件

  • 互斥条件:一个资源每次只能被一个进程使用;若其他进程申请使用该资源,必须等到该资源被释放为止。

  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

  • 不可剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。

  • 循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系。

 

预防死锁

死锁预防的基本思想是:只要确保死锁发生的四个必要条件中至少有一个不成立,就能预防死锁的发生,具体方法包括:

  • 打破互斥条件:互斥条件无法破坏。

  • 打破请求与保持条件:可以实行资源预先分配策略(进程在运行前一次性向系统申请它所需要的全部资源,若所需全部资源得不到满足,则不分配任何资源,此进程暂不运行;只有当系统能满足当前进程所需的全部资源时,才一次性将所申请资源全部分配给该线程)或者只允许进程在没有占用资源时才可以申请资源(一个进程可申请一些资源并使用它们,但是在当前进程申请更多资源之前,它必须全部释放当前所占有的资源)

缺点:在很多情况下,无法预知一个进程执行前所需的全部资源,因为进程是动态执行的,不可预知的;同时,会降低资源利用率,导致降低了进程的并发性。

  • 打破不可剥夺条件:允许进程强剥夺使用其他进程占有的资源,从而破坏不可剥夺条件。即,一个进程占有了一部分资源,在其申请新的资源且得不到满足时,它必须释放所有占有的资源以便让其它线程使用。

缺点:这种预防死锁的方式实现起来困难,会降低系统性能。

  • 打破循环等待条件:实行资源有序分配策略,破坏环路条件。对所有资源排序编号,所有进程对资源的请求必须严格按资源序号递增的顺序提出,即只有占用了小号资源才能申请大号资源,这样就不产生环路,预防死锁的发生。

缺点:方法低效,影响进程执行的速度,甚至阻碍资源的正常分配。

 

避免死锁

死锁避免的基本思想是:动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。安全状态值如果系统能按某个顺序为每个进程分配资源(不超过其最大值),那么系统状态是安全的。即,如果存在一个安全序列不会导致死锁,那么系统处于安全状态。

银行家算法:该算法检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。这样申请者就可以很快完成其计算,然后释放它占用的资源,从而保证了系统中所有进程都能完成,所以可避免死锁的发生。

银行家算法步骤:

检查此次申请是否超过了之前声明的最大需求数。

检查此时系统剩余的可用资源是否还能满足这次请求。

试探着分配,更改各数据结构。

用安全性算法检查此次分配是否会导致系统进入不安全状态。

安全性算法步骤:

检查当前的剩余可用资源是否能满足某个进程的最大需求,如果可以,就把该进程加入安全序列,并把该进程持有的资源全部回收。

不断重复上述过程,看最终是否能让所有进程都加入安全序列。

 

检测死锁

检测死锁是指操作系统周期性地执行死锁检测例程,检测系统中是否出现“环路等待”。检测到以后对死锁的进程进行解除。