死锁是指两个或多个进程在执行过程中,因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法向前推进。
死锁的发生原因
死锁的发生必须同时满足以下四个必要条件:
-
互斥条件
资源不能被共享,一次只能被一个进程使用。例如,打印机在同一时刻只能被一个进程使用,如果一个进程正在打印,其他需要打印的进程就必须等待。 -
请求与保持条件
一个进程在请求新的资源的同时,还保持对原有资源的占有。比如,一个进程已经占用了内存空间A,又去请求磁盘空间B,而磁盘空间B已经被另一个进程占用,此时这个进程既不释放内存空间A,又等待磁盘空间B。 -
不可剥夺条件
已被分配的资源不能被强制性地剥夺,只能由占有它的进程自行释放。例如,一个进程占用了CPU资源,其他进程无法强制将其从CPU上剥夺下来,只能等待该进程主动释放。 -
循环等待条件
存在一个进程链,链中的每个进程都至少占有一个资源,同时又等待链中下一个进程所占有的资源。比如,进程P1持有资源R1并等待资源R2,进程P2持有资源R2并等待资源R1,这就形成了一个循环等待。
避免死锁的方法
为了避免死锁的发生,可以采用以下几种策略:
-
预防死锁
通过破坏死锁的四个必要条件之一来预防死锁的发生。-
破坏互斥条件:将资源改为可共享资源,但这在很多情况下是不现实的,因为有些资源本质上就是不可共享的,如打印机。
-
破坏请求与保持条件:要求进程在请求资源时,必须一次性申请其在整个运行过程中所需要的全部资源。如果系统有足够的资源分配给该进程,则一次性分配给它;否则,让该进程等待,直到系统能满足其全部资源需求为止。例如,一个进程在运行前,必须先申请到它需要的所有内存空间、磁盘空间和其他资源,否则就不让它运行。
-
破坏不可剥夺条件:允许进程强行从占有者手中夺取某些资源。例如,对于某些资源,系统可以采用剥夺的方式,当一个进程等待时间过长时,系统可以强制剥夺其他进程占用的资源分配给它,但这可能会导致其他进程运行失败。
-
破坏循环等待条件:通过规定资源的使用顺序来避免循环等待。例如,给系统中的资源编号,进程申请资源时必须按照编号顺序申请。如果进程P1已经占有了编号为1的资源,那么它只能申请编号大于1的资源,这样就不会出现循环等待的情况。
-
-
避免死锁
系统在进行资源分配时,动态地检查系统的状态,以确保此次分配不会导致死锁。一种常见的方法是采用银行家算法。-
银行家算法:系统在进行资源分配时,先计算此次分配后系统的状态是否安全。安全状态是指系统能按某种序列为进程分配所需的资源,而不会导致死锁。如果此次分配会导致系统进入不安全状态,那么系统就拒绝此次分配,等待进程释放资源后再重新尝试。例如,系统中有多个进程多种和资源,每个进程都有最大需求资源量和当前已分配资源量,系统会根据这些信息来判断是否可以安全地分配资源。
-
-
检测与恢复
允许系统进入死锁状态,但通过检测死锁并采取措施恢复来解决死锁问题。-
死锁检测:系统定期检查是否存在死锁。例如,系统可以设置一个检测程序,定期检查进程的资源分配情况和等待情况,通过构建资源分配图来判断是否存在循环等待。
-
死锁恢复:一旦检测到死锁,系统可以采取措施来解除死锁。一种方法是选择一个或多个进程作为牺牲品,剥夺它们的资源并将其分配给其他进程,以打破死锁。例如,系统可以选择等待时间最长的进程作为牺牲品,剥夺其占用的资源,让其他进程能够继续运行。
-