别把它想得太玄。你可以把银行家算法理解成一句大白话:钱不是不能借,而是借出去以后,后面还得有路可走。
银行家算法最容易把人绕晕的地方,是一上来就看到一堆矩阵。其实你先别管矩阵,先记一句人话:系统手里现在剩下的资源,能不能一个一个把大家安全送走。
如果能,那当前状态就叫安全。如果怎么排都排不出一条“都能顺利做完”的路线,那这个状态就危险,系统就不该再乱答应新的资源请求。
下面这组数据是经典练手规模,不大,正适合拿纸笔一步一步跟。
| 进程 | Allocation | Max | Need = Max - Allocation |
|---|---|---|---|
| P0 | (0,1,0) | (7,5,3) | (7,4,3) |
| P1 | (2,0,0) | (3,2,2) | (1,2,2) |
| P2 | (3,0,2) | (9,0,2) | (6,0,0) |
| P3 | (2,1,1) | (2,2,2) | (0,1,1) |
| P4 | (0,0,2) | (4,3,3) | (4,3,1) |
当前系统手里还剩下的资源是 Available = (3,3,2)。接下来要做的事很朴素:看看这点家底,先能不能满足某一个进程的 Need。
下面这个动画只做一件事:按安全性检查的思路,一步一步找安全序列。每一步我都尽量用做题时会冒出来的那种口语去讲,不走教材腔。
手算时不要一口气盯着五行一起看,那样最容易乱。你就像排队放人一样,一次只看一个问题:它现在缺的,系统给不给得起。
初始 Available = (3,3,2) 先看 P1:Need = (1,2,2) 因为 (1,2,2) <= (3,3,2),所以 P1 能先做完 P1 做完后会归还 Allocation = (2,0,0) 新的 Available = (3,3,2) + (2,0,0) = (5,3,2) 再看 P3:Need = (0,1,1) 因为 (0,1,1) <= (5,3,2),所以 P3 也能做完 P3 归还 (2,1,1) 新的 Available = (7,4,3) 接下来 P4:Need = (4,3,1) <= (7,4,3) P4 做完后归还 (0,0,2) 新的 Available = (7,4,5) 接下来 P0:Need = (7,4,3) <= (7,4,5) P0 做完后归还 (0,1,0) 新的 Available = (7,5,5) 最后 P2:Need = (6,0,0) <= (7,5,5) P2 也能做完 所以一条安全序列可以是:
如果你只想记住最核心的话,那就是:先找一个现在就能完成的人,让他做完并归还资源,再看下一个。只要能一直找下去,直到所有进程都能排进去,这个状态就是安全的。