操作系統 OS 與內核 Kernel 有什么區別?
通用底盤技術
Canoo公司有一項核心技術專利,這就是它們的通用電動底盤技術,長得是這個樣子,非常像一個滑板:
這個帶輪子、有電池、能動的滑板已經包含了一輛車最核心的組件,差的就是一個外殼。
這個看起來像滑板的東西就是所謂的電池系統和底盤一體化技術,Canoo公司在它們的通用底盤上加裝不同的外殼就能制造出不同的車型。
什么是內核?
在上面這個示例中,包含輪子以及電池系統的底盤就好比內核,而套上外殼加上椅子以及內飾后的整體成品就好比操作系統。
內核僅僅是操作系統的一部分,是真正與硬件交互的那部分軟件,與硬件交互包括讀寫硬盤、讀寫網盤、讀寫內存以及任何連接到系統中的硬件。
除了與硬件交互外,內核還負責分配資源,分配什么資源呢?所謂資源就是硬件,比如CPU時間、內存、IO等等,這些都是資源。
現在我們知道了內核負責分配資源,那么問題來了,要怎么分配這些資源呢?答案就是以進程的形式來分配資源。
怎么分配呢?
一句話:虛擬大法好。
每個進程都認為自己在獨占CPU,這通過CPU時間片來實現,內核讓CPU在各個進程之間快速切換,這樣程序員寫好程序員后直接運行即可,即使在單核系統中運行成百上千個進程都沒有問題。
每個進程都認為自己在獨占內存,這通過虛擬內存來實現。
有的同學可能會問,為什么都要虛擬化呢?
答案顯而易見,因為計算機系統內的資源是有限的,我們只有幾個CPU核心、幾個G的內存,但卻要同時運行幾百幾千個進程,除此之外我們別無它法。
如果你還知道有其它更高效的方法那么趕緊放下手機,馬上將你的思想寫成論文發表出來,下一屆的圖靈獎非你莫屬,當然在發表獲獎感言的時候一定要記得表示是受到了【碼農的荒島求生】這個公眾號的啟發才想到的。
因此,內核的職責就是以進程的形式來分配CPU時間,以虛擬內存的形式來分配物理內存,以文件的形式來管理IO設備。
什么是操作系統?
然而只有一個內核實際上是做不了什么真正有用的事情,就像上面示例中那個通用底盤一樣,這個底盤確實能跑起來,但你沒辦法開著這樣一個底盤出去浪,因為這個底盤很難用。
因此,你不得不加裝上方向盤、座椅以及車身外殼等,同樣的道理,內核是給人用的,為了與內核交互,發明了命令行以及圖形界面GUI。
除了給普通用戶提供使用的接口之外,操作系統還需要給程序員提供編寫程序的接口,當我們寫的程序依賴內核提供的服務時是該怎么辦呢?
有的同學說我們需要依賴內核提供的服務嗎?
想一想,進行網絡編程時你有沒有自己編寫過處理TCP/IP協議棧數據的代碼?你有沒有自己寫代碼從網卡上收發數據?都沒有,實際上你需要做的僅僅是簡單的調用一些socket接口就可以了。
網絡編程僅僅是其中的一項,其它還包括文件IO、創建進程、創建線程等等等等,這些是內核提供的,那么我們該怎么使用呢?
答案就是通過所謂的系統調用,system call。
通過系統調用,我們可以像使用普通函數那樣向操作系統請求服務,當然,直接使用系統調用是非常繁瑣的,因此通常會在這之上提供一層封裝。
在Windows平臺就是給程序員提供編程接口的是Windows API,這層API包羅萬象,不但包括上文提到對系統調用的封裝,還包括其它功能,像創建帶有圖形界面的應用程序等等。
但在Linux世界你找不到一種類似Windows API的東西,畢竟Windows是微軟自家產品,什么都可以打包起來,Linux只是一個開源的內核,如果一定要找一個類似的東西話那就是libc,也就是C標準庫,這里同樣包括了對系統調用的封裝以及一些庫函數,但libc不包含創建帶有圖形界面應用程序的功能。
現在我們知道了,操作系統需要提供兩種接口:
給用戶提供操作接口。
給程序員提供編程接口。
這些就是好比汽車的外殼,我們(用戶和程序員)看得見摸得著,外殼加上底盤——也就是內核,才是功能完善的操作系統。
各種各樣的操作系統
實際上我們熟悉的Linux只是內核而不能稱得上是操作系統,Ubuntu則可以認為是操作系統,其內核是Linux;RedHat也是操作系統,其內核同樣是Linux;我們可以看到,盡管Ubuntu和RedHat是不同的操作系統,但其內核可以是相同的。
這就好比它們可以基于同樣的底盤打造出不同的車型。
而我們熟悉的Windows也是操作系統,其內核是Windows NT內核。
總結
內核就像本文開頭提到的電動底盤,包含了一個汽車的最核心元素;但這樣一個底盤并沒有什么實際用處,當搭配上外殼以及座椅后才是一輛真正有用的車,這就好比操作系統。值得注意的是,不同的操作系統可以有相同的內核。
當我們在使用方便的智能手機以及個人PC時不應忘記,正是操作系統在背后的默默工作讓一堆硬件電路變得這么好用。
希望這篇文章對大家理解操作系統以及內核有所幫助。