一文揭開操作系統的神秘面紗
1 操作系統簡介
在如今的世界里,絕大多數人都會對Windows,Linux及MacOS等操作系統有一定的使用經驗,但是很多時候對操作系統本身并沒有太多感知。畢竟與用戶直接打交道的大多數是各種炫酷的客戶端軟件,包含精美的字體、圖標和圖片等。
圖1 Windows10
雖然一般來說這樣漂亮的用戶界面通常不屬于操作系統,但可看作它是操作系統的一部分,通過操作系統來完成其底層復雜的與硬件層面的交互工作。
現今的計算機是一個極其復雜的系統,一般由一個或多個處理器,以及一些主內存、磁盤、網絡接口、各種外設以及各種其他輸入/輸出設備組成。如果每個程序員都必須詳細了解所有這些硬件層面的原理和機制,然后才能編寫相應的代碼,那么可想而知這樣的效率會有多低。
圖2 操作系統所處層次結構
此外,管理所有這些組件并優化使用它們是一件非常困難的工作。因此,計算機配備了一層稱為操作系統的軟件,其作用是為用戶程序提供簡潔方便的計算機模型,并統一管理所需要的資源。
圖3 計算機基本硬件組成
在這里,我們看到計算機最底部是各種硬件,包括芯片,主板,磁盤,鍵盤,顯示器等。在硬件之上則是軟件。大多數計算機都有兩種操作模式:內核模式和用戶模式。
內核模式Kernel Mode:
在內核模式下,程序具有硬件的所有控制權限,可以執行所有CPU指令,可以訪問任意地址的內存。在內核模式下的任何異常都是災難性的,將會導致整臺機器停機。
用戶模式User Mode:
在用戶模式下,程序沒有對硬件的直接控制權限,也不能直接訪問地址的內存。程序是通過調用系統接口API來訪問硬件和內存。在這種保護模式下,即使程序發送崩潰也是可以恢復的。
操作系統可以看作是最基本的軟件,它運行在內核模式(也稱為管理程序模式)下。在這種模式下,它可以完全訪問所有硬件,并且可以執行機器可以執行的任何指令。
而在用戶模式下運行的一般都為直接面向用戶的應用軟件,在該模式下只能使用一部分機器指令。特別是,那些影響機器控制或「I/O輸入輸出」的指令在用戶模式程序中是禁止的。
2 操作系統作用
看起來操作系統好像就是橫跨在用戶應用軟件和底層硬件之間的橋梁,通過運行在內核模式進行硬件的控制和調度。事實上,操作系統的作用可大致分為兩大方面。
作為計算機硬件的抽象層
大多數計算機在機器語言級別上的體系結構是極其原始的,主要說的是指令集,內存組織,I/O處理和總線結構。在這樣的結構下是沒辦法進行自定義編程的,特別是對于I/O操作而言。因而,沒有理智的程序員愿意在硬件級別處理磁盤和內存。
為了解決這樣尷尬的局面,從而產生了一個稱為磁盤驅動程序的軟件。它用來處理硬件并提供一個接口來讀取和寫入磁盤塊,而使得我們無需關注其細節。這本身就是操作系統最初具有的功能之一,包含許多用于控制I/O設備的驅動程序。
圖4 讓人頭疼的設備驅動
但是對于大多數應用程序來說,光有驅動程序是不夠的。因此,所有操作系統都為使用磁盤提供了另一層抽象而又便于理解的概念:文件。程序可以創建,寫入和讀取文件,而不需要處理硬件層面中復雜的工作原理和實現細節。
這種所謂對硬件層面的抽象是管理所有這些復雜底層硬件的關鍵。一個好的抽象系統將幾乎不可能完成的任務變成可以進行管理的任務。所以事實上操作系統所干的事,首先是定義和實現抽象。然而是使用這些抽象來解決上層用戶的問題。
圖5 「文件」是操作系統最重要的抽象概念
「文件」是幾乎每個計算機用戶都可以理解的一種抽象。一個文本,一個照片,一封保存的電子郵件,一首周杰倫的歌或一個網頁,這些都可看作是抽象出來的文件。正是通過操作系統的抽象作用,使得我們可以在處理文本、照片、郵件的時候只需要點擊幾下,而不需要去考慮在SATA磁盤中數據的存放格式發生了如何變化。
圖4 操作系統對硬件層的抽象
顯而易見的是,操作系統的主要任務之一是隱藏硬件,并以簡單且好看的抽象形式呈現程序,以方便用戶的使用。這也是Windows系統持續幾十年的市場占額的原因所在,相較于其它的系統,Windows以更接近用戶體驗的抽象方式從而贏得了市場。
作為計算機的資源管理器
上面的作用簡單來說就是操作系統為用戶層面的應用程序提供了一種硬件的抽象,是自頂向下的作用。除此之外,操作系統還可以作為自底向上的中間人對應用程序所需要的資源進行管理和分發。在自下而上的流程中,操作系統的工作是在需要處理器、內存和I/O設備的各種程序之間提供有序且受控的分配。
圖4 操作系統對底層資源的管理
打個比方,我們知道操作系統允許多個程序同時運行并占用內存。想象一下,如果在一臺計算機上運行的三個程序都試圖在同一臺打印機上同時打印輸出,將會發生什么。三個程序調用打印機打印可看作是對資源對請求,如果沒有操作系統對資源請求的管理和分配,那么整個計算機的輸出結果將會是完全混亂的。
圖5 多個程序同時調用打印機的錯誤輸出
打印機這個例子還只是最簡單直接的資源請求和分配問題,而其它比如網絡資源、內存資源的請求沖突問題的影響就更大了。如果處理不好資源請求之間的問題,不同應用程序之間則會發生嚴重的串擾,以致出現各種無法調試的錯誤。
操作系統主要是以時間和空間這兩種方式進行復用或共享資源。對資源進行時分復用時,不同的程序或用戶輪流使用它。他們中的第一個開始使用資源,然后再使用另一個,依此類推。
圖6 操作系統在時間維度上分配資源
這實際上就是所謂時間片的概念,在時間的緯度上為每個程序分配一段資源占用的機會。還是共享打印機的例子,當有多個程序都想用打印機的時候,就按照時間發送的順序在打印機上線性排序,一個一個來。
另一種是空間多路復用。最主要的區別在于不是每個程序輪流使用,而是每個程序都獲得了一部分資源。
圖7 操作系統在空間維度上分配資源
例如,通常將主存儲器劃分為幾個可同時使用的區域,每個程序可以同時占用。假設有足夠的內存來容納多個程序,那么相較于所有內存分配個一個程序而言,一次將多個子內存分配給多個程序就更有效。
當然,這會引起公平性以及安全性等問題,這也是操作系統需要解決的問題之一。進行空間多路復用的另一個資源是磁盤。
在絕大數系統中,單個磁盤可以同時容納來自多個程序或用戶的文件。而操作系統在這其中的作用就是根據用戶或程序來確定其對應的一塊磁盤區域,從而保證程序正常的運行。
總結
操作系統復雜性絕不是幾篇文章可以介紹的完的,但是這些理論上的思想正是操作系統架構形成的基礎。了解操作系統能夠讓我們真正走進程序代碼執行的內部,從高級語言出發進而理解硬件層面的執行,從而能夠真正從平臺及系統層面優化我們代碼的性能。
作者簡介:我是安醬,一個稀里糊涂地進了大廠的業余碼農。分享全棧技術,目標架構師。關注我,一起向技術大牛進階!
本文轉載自微信公眾號「 業余碼農」,可以通過以下二維碼關注。轉載本文請聯系 業余碼農公眾號。