最近在複習<操做系統>的重修考試o(╥﹏╥)o, 原來準備戴上耳機來一場硬核複習, 可是發現死記硬背沒用還浪費生命, 只好僞裝喜好這一門學科, 順帶研究了下一些OS的底層原理, 期間經過研究銀行家算法原理時發現了一些有趣的現象, 順便聯想到一些哲學思想, 想和你們分享一下: )web
首先談談OS在預防死鎖的時候和進程之間進行了哪些博弈.算法
操做系統進程死鎖是一個古典問題, 因爲進程之間的不信任關係, 2個進程有可能造成一種膠着狀態, 即循環等待, 無盡的浪費時間. 爲啥會出現這種狀況呢? 根據做業的邏輯, 一個進程完成一個任務若是須要2個以上的資源, 必定要前後得到全部資源的控制權後纔會開始執行, 好比一個RPG遊戲進程保存遊戲進度的時候須要更新2個文件: 劇情進度文件A和主角當前屬性文件B. 遊戲得到了文件A的write權限後並不會當即寫入A, 而是再去申請文件B的write權限, 可是若是期間B已經被其它惡意軟件得到了write權限(由於對OS而言, 只要有進程索要一個不可共享資源的權限時, 只要合法就沒有任何理由拒絕), 這時候遊戲會一直等待B的佔用被釋放, 等待的期間本身對A的控制權不會釋放(由於釋放了就表明了示弱, 進程之間不信任意味着進程之間不能協商!).瀏覽器
以上這個狀況就造成了一個單向無盡等待, 真實環境下不會出現這種狀況, 由於遊戲配置文件是屬於遊戲的私有物, 其餘惡意軟件沒有權限訪問這個文件, 遊戲內部更不會出現死鎖, 由於內部線程之間能夠協商和變通.安全
真實狀況下的死鎖是循環等待形成的, 最簡單的循環等待是雙向無盡等待, 這是因爲2個進程對多個公共資源的惡性競爭引發的服務器
若是你對這一套解釋雲裏霧裏的話, 這兒有一個很是通俗的類比: 在一個參觀中只剩下一雙筷子, 2只筷子散落2處, 如今也只有2個顧客, 只要誰搶到了2只筷子就能夠先吃飯, 對方就不能干擾, 由於法律規定不能干擾他人吃飯, 法律的規定看似很公平, 可是有一種特殊狀況不容忽視: 當2我的分別搶到一隻筷子後都期望對方放棄筷子, 讓本身先吃, 對方後吃. 從時間效益的角度看, 不管誰先吃後吃, 總時間必定, 沒有效率差異, 可是對於食客我的而言, 吃飯前後順序和本身的利益息息相關, 因而誰都不肯意先放棄手中的筷子, 2我的僵在一塊兒, 無盡的等待, 可是這樣作又沒有違法, 因而這個局面無解, 造成了死鎖.性能
這個例子映射了經典的囚徒困境問題, 即我的利益最大化不等於集體最優.操作系統
囚徒困境(prisoner's dilemma)是指兩個被捕的囚徒之間的一種特殊博弈,說明爲何甚至在合做對雙方都有利時,保持合做也是困難的。囚徒困境是博弈論的非零和博弈中具表明性的例子,反映我的最佳選擇並不是團體最佳選擇。雖然困境自己只屬模型性質,但現實中的價格競爭、環境保護、人際關係等方面,也會頻繁出現相似狀況。線程
如圖, 對於一個囚徒來講, 若是本身和對方都隱瞞對方, 則皆大歡喜, 雙雙釋放, 若是都揭發對方, 雙雙坐牢1年, 若是本身隱瞞但被對方揭發則本身坐牢5年對方釋放, 若是本身揭發對方對方隱瞞則本身釋放對方坐牢5年. 若是他們是親人那頗有可能都坦承從而達到全局最優, 可是若雙方都不信任, 對於我的來講最好的選擇是揭發對方, 正中警察圈套!因此說, 在個體之間不信任的前提下, 囚徒困境是很難有解的.blog
仔細想一想看, 真的無解嗎? 其實有解, 若是我遇到這種狀況, 按之前的性格, 直接上去抽對方也不會和他僵持(誇張了, 表達這個意思). 可是如今我不想和他浪費時間, 若是對方執意要先行, 我就把筷子給他, 等他吃完我再吃, 這樣既節省了個人時間也節省了對方的時間, 更節省了飯店的時間. 可是現實中不多有人會這麼作, 在沒有控制全局的leader的前提下, 大多數人都會僵持.遊戲
進程之間難道不也是這樣嗎? 若是一個進程發現本身的頗有可能處於死鎖狀態的時候自願放棄手中的資源, 隔段時間再重新請求, 頗有可能想要的資源順利獲得了, 這是真實可行的, 大家能夠本身分析分析是否是這個道理, 一個進程只要暫時犧牲本身的時間, 從數學指望的角度就必定能得到以後的全部資源, 從而爲本身節省更多的時間. 可是進程和人是同樣的, 確實有少部分進程心胸寬廣, 願意放棄資源, 或者它以爲資源不充足的狀況下能夠照樣辦事, 辦完後把手頭的資源也釋放, 讓對方進程從而也得以繼續, 可是大多數進程都是誰都不肯先妥協, 誰都不肯先吃虧, 相互抵制, 從而形成了囚徒困境, 產生了死鎖.
既然囚徒困境在充滿冷漠和質疑的世界上是無解的, 那就須要一個leader來控制局面, 這個leader就是OS. 但正如以前搶筷子問題, 即便兩人的爭吵引來了城管, 城管由於公平的原則也不能剝奪任何人的筷子給與對方, OS也不能強行把一方的資源給另外一方先使用, 只能尋找其餘的辦法, 因而就產生了'銀行家算法'.
回到以前的飯館, 飯館經理通過深思熟慮以後, 制定了一條行爲準則, 專門針對飯店裏存在的死鎖問題, 這個規則不是爲了死鎖發生後怎樣解決, 而是爲了從根源上預防死鎖, 法案規定, 筷子和其餘餐具再也不直接讓顧客自由拿取, 而讓顧客排隊領取, 而且每一個顧客進門以前要登記, 同時彙報本身對每一種餐具的數量需求, 若是是團體顧客就提供每人的需求總和.
爲了簡化例子, 仍是拿剛剛2我的掙一隻筷子的狀況吧, 2我的A和B對筷子的需求量都是2, A申請領取第一支筷子的時候, 服務員會模擬一個假設: 假如把筷子給了A, 剩下1只筷子, 和一個須要2只筷子的B, 這樣是否安全? 若是我把另一隻先給A, 等A知足後再把2只筷子給B, 正好, 沒有危險. 因而服務員愉快的將第一支筷子給到A. 而後當B索要一隻筷子的時候, 雖然庫存中正好還有1只筷子, 但服務員仍是拒絕了B的請求, 緣由是, 若是筷子給了你, 大家有可能發生死鎖.
這項規定的邏輯是, 你若是須要2只筷子, 卻只獲得了1只, 那你有權利不滿, 有權利爭吵; 可是若是2只筷子都給你了, 你給我閉嘴乖乖吃飯, 快點吃飯, 吃完把筷子還給我! 若是你進門時說只須要1只筷子, 如今要2只, 對不起, 給我滾! 這個方法是有代價的, 由於也許A並非同時須要2只筷子, 有可能A用一隻也能吃(也正打算用1只吃飯, 另一隻忽然不想要了), 這種狀況下也許把第二隻筷子給到B是全局更好的方案, 可是服務員也不想冒險, 由於萬一一會A又來索要第2只筷子了怎麼辦.
這就是銀行家算法, 銀行家算法是一種妥協的算法, 雖然避免了死鎖可是有機會成本的開銷. OS不可能假定每一個進程都是高素質的, 只能考慮最壞的狀況, 也就是每一個進程不獲得全部的資源不死心. 在每一個進程請求資源的時候進行假設, 判斷是否會形成不安全狀態. 但如圖所示, 不安全狀態是包含死鎖狀態的, 也就是說系統不安全並不必定形成死鎖, 銀行家算法經過封殺全部不安全狀態從而全面避免了死鎖, 但資源浪費的狀況也沒法杜絕. 悠悠青史告訴咱們, 在沒有第三方權威約束下獨立思惟永遠沒法相互協做, 只能實現個體最優, 一個社會沒有上帝引導, 經過自由發展永遠沒法共產.
銀行家算法的本質是OS的猜想算法, 是OS與進程以及進程與進程間的不信任引發的. 計算機軟件自己就是由多個不信任的軟件層結合起來的, 好比OS不信任瀏覽器, 瀏覽器不信任服務器, 服務器不信任用戶, 在咱們web領域, 這種4層不信任體系成爲了了網頁性能的瓶頸, 每一層不信任都帶來了額外的時空開銷. web的將來應該是高內聚低耦合的, 瀏覽器也應該從應用軟件變成系統軟件, 從而減小臃腫的層次結構, 提升互聯網服務的性能, 目前爲止這仍是一場夢.