面试模拟场景
面试官: 你能解释一下什么是死锁吗?死锁产生的四个必要条件是什么?如何预防死锁?
参考回答示例
什么是死锁?
定义:
- 死锁是指在一个多进程系统中,两个或多个进程(或线程)因为互相等待对方释放资源而导致永远无法继续执行的情况。简而言之,死锁是指一组进程之间的循环等待资源的现象,导致它们都无法执行下去。
例子:
- 假设有两个进程,进程A持有资源R1,进程B持有资源R2。现在进程A需要资源R2才能继续运行,而进程B需要资源R1。由于这两个进程都在等待对方释放资源,因此陷入了死锁状态,无法继续运行。
死锁产生的四个必要条件
根据著名的Coffman条件(也称为死锁产生的四个必要条件),死锁的产生必须同时满足以下四个条件:
-
互斥条件:
- 至少有一个资源必须是被独占使用的,即同一时间只能有一个进程能够使用该资源。如果一个进程占用了资源,其他进程必须等待,直到资源被释放。
-
请求保持条件:
- 一个进程已经持有至少一个资源,并且正在等待获取其他资源,而这些资源被其他进程持有。换句话说,进程在持有资源的同时,还在等待其他资源。
-
不剥夺条件:
- 资源不能被强行剥夺,资源只能由持有它的进程主动释放。当一个进程持有资源时,该资源只能在进程完成任务后自愿释放,不能被其他进程强行夺取。
-
循环等待条件:
- 存在一个进程等待链,其中每个进程都在等待下一个进程持有的资源,形成一个环形等待链。例如,进程A等待进程B持有的资源,进程B等待进程C持有的资源,而进程C又在等待进程A持有的资源,从而形成一个循环等待。
如何预防死锁?
预防死锁的方法通常分为以下几种策略:
-
破坏互斥条件:
- 在某些情况下,可以尝试使资源不具备互斥性,允许多个进程并发访问。例如,将资源转换为可共享的资源(如只读文件),这样就不需要独占访问了。(如使用SPOOLing技术)
-
破坏请求保持条件:
- 要求进程在开始执行前一次性请求它所需要的所有资源。如果所有资源都能分配给该进程,那么它可以继续执行;否则,它必须释放所有已持有的资源,并重新尝试获取所有资源。
-
破坏不剥夺条件:
- 允许进程在请求新资源时,如果其请求的资源不可用,则必须释放它已经持有的所有资源。通过这种方式,避免了进程持有资源的同时还在等待其他资源的情况。
-
破坏循环等待条件:
- 系统为所有资源赋予一个编号,并要求进程按编号顺序请求资源。每一个进程按编号递增的顺序请求资源,释放则相反。
总结
-
死锁的定义: 死锁是指多个进程因为互相等待对方释放资源而导致永远无法继续执行的情况。
-
死锁的四个必要条件:
- 互斥条件: 资源只能被一个进程独占使用。
- 请求保持条件: 一个进程持有资源的同时,还在等待其他资源。
- 不剥夺条件: 资源不能被强行剥夺,只能由持有它的进程主动释放。
- 循环等待条件: 存在一个进程等待链,形成一个环形等待。
-
预防死锁的方法:
- 破坏互斥条件(SPOOLing技术)、请求保持条件(资源一次性分配)、不剥夺条件(资源剥夺)或循环等待条件(资源有序分配)。