歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 關於Linux和Windows的內核區別

關於Linux和Windows的內核區別

日期:2017/2/28 15:55:32   编辑:Linux教程

關於Linux和Windows的口水站已經很多了。本文企圖從技術角度來比較下2個主流操作系統的異同。偏重於內核部分。

一、二者區別:

我覺得二者最大的區別在於Windows是個商業軟件,而Linux是開源軟件。商業軟件的好處是可以集中一大批人力物力做一件事情。容易統一,兼容(因為客戶需求)。而開源的好處在於靈活,開放。

在下面的比較中,我一般先介紹下Windows的,然後再介紹Linux的。

1、觀念:商業 VS 開源

Windows是個商業軟件,它的源碼是保密的. 當然,其他非MS的人也還是有機會看到源碼的. 如果你和MS 簽訂一個NDA(NON DISCLOSURE AGREEMENT),那麼你也有可能拿到Windows代碼.

言規正傳,我覺得商業也還是有好處的。比如兼容性好,我以前用WDM寫一個驅動,最多改下編譯選項就可以在WIN 98, WIN 2K, WIN XP下運行。十分方便。而如果換成Linux,那麼你只好祈禱不同的內核版本之間沒改那些你用到的頭文件,函數接口。否則就要改代碼了。

同時,開源的好處是適合學習,十分靈活。我覺得Linux十分適合學校,學生。因為開源,當你發現不明白的地方的時候,可以直接去看源碼(還記得RTFS? )。看不懂還可以到論壇上問。而對於Windows,你想了解它的內部機制就只好GOOGLE,然後祈禱了。比較好的一個資源是MSDN下面的一個雜志,其中有一個主題叫UNDER THE HOOD, 或者搜搜 BUGSLAYER 也可以。這2個專題的作者Matt Pietrek和John Robbins都是大牛級的人物。

順便說下UNDER THE HOOD 這個名字本身。www.linuxidc.com以前一直不太理解,因為查字典的話,HOOD 的意思也就是個蓋子。那麼蓋子下面有啥呢?為啥要看蓋子下面呢?

來到美國之後,我漸漸明白了。HOOD 在這裡應該理解為汽車的引擎蓋。在美國,汽車是很普遍的。如果你開車,但是從來沒打開過引擎蓋,那麼說明你只會用,而不了解汽車內部。那麼如果你打開蓋子看看呢?就可以看到很多內部細節,比如發動機啥的了。

在美國這個汽車王國,很多軟件術語和汽車有關,因為人們日常生活中對汽車也很了解。比如“引擎”這個詞,以前玩3D游戲的時候,常會看到介紹說,本游戲采用了最新的3D引擎。啥意思呢?就是游戲最核心的部分(汽車引擎)已經升級了。不是只把外面的人物形象改了下而已。

另外,開源軟件也經常用汽車來類比。開源意外著你買了車(軟件)後,可以隨便拿到一個修理廠去修。也就是什麼人都可以改,只要他懂。而COPY RIGHT 軟件呢,就是你買了車,但是引擎蓋子是鎖著的,壞了只能去生產廠家修,其他人修不了。如果萬一生產廠家不想修或者不會修呢?那你就只能認命了。

扯得有點遠了,打住。

1.1、發布:2進制 VS 源碼

這裡主要討論下Windows和Linux在發布程序采用的不同的形式和觀念,這些和前面的商業還是開源的基本觀念是聯系在一起的。

在Windows 世界,安裝程序幾乎全部都是以二進制形式發布的。也就是說,用戶下載了一個程序,然後雙擊,一路NEXT,NEXT,NEXT就可以了。這個方法很適合初學者。在Linux世界也有類似的機制,比如YUM, APT-GET 等。不過YUM和APT-GET都是比較晚才出現的,在那之前,在Linux世界安裝程序要更麻煩些。

有的時候,Linux的YUM, APT-GET還不夠用。比如有的人寫的一個小軟件,沒有放到這些大的公共的庫裡面。這時,你就會發現他們一般提供一個或者一堆源文件,然後需要使用者自己下載,“編譯”,安裝。這也就是Linux世界常見的源代碼發布的形式。

一開始的時候,十分不習慣Linux的這種發布形式。用慣了Windows的雙擊安裝,總覺得Linux的安裝很麻煩,又要自己./CONFIGURE, MAKE, MAKE INSTALL. 萬一這個軟件又依賴於其他的庫,那麼又要自己去找那些庫,萬一那些庫又依賴其他的庫...... 另外,各種庫的版本也是一個問題,萬一不兼容,那麼又要找一個兼容的。

為什麼Linux世界這麼多源代碼發布呢?為什麼Windows世界流行2進制文件發布,而不是源代碼呢?關於後者,很好解釋,因為Windows那邊很多源代碼都是商業秘密,是不公開的。同時,Windows的程序用到的那些庫在一般的系統裡都裝好了。所以2進制發布可行,也十分方便。

關於前一個問題,我覺得源代碼發布的一個好處是可以在編譯的時候進行一些優化和設置。比如同樣的代碼,在32或64位平台下編譯的時候可以進行適當的優化。另外,用戶也可以在編譯的時候設置一些開關,這樣在編譯期間的優化一般要好於運行時間的優化。

不過源代碼發布的一個壞處就是對使用者要求較高。如果運行configue,make命令順利的話還好。如果萬一不順利,要自己改下頭文件啥的,無疑是一般的使用者無法做到的。另外庫之間的依賴關系如果是人手工處理的話也十分麻煩。好在Linux世界後來有了YUM APT-GET之類的包管理系統。大多數軟件都可以很方便的安裝了。

2、進程及其創建 CreateProcess VS fork+execv

在Windows世界,創建進程最常用的WIN 32 API 是 CreateProcess以及相關函數。這個函數需要一堆參數(Windows API 的特點),不過很多參數可以簡單的用NULL, TRUE OR FALSE來表示。另外,你直接告訴它要執行的是哪個文件。

到了Linux世界,我模糊的知道fork是用來創建一個新進程的。但是當我看fork的函數說明的時候,呆住了。因為fork不需要任何參數。習慣了 CreateProcess 的10來個參數,突然換成一個不要任何參數的函數,感覺很奇妙。一方面覺得似乎事情簡單了很多,不用去把10來個參數的每個意思都搞明白。另外一方面又很疑惑,我怎麼告訴它我要執行某個文件呢?

後來才知道,Linux中的進程的含義和Windows中是不一樣的。Linux中的進程本身是可以執行的。而Windows中,進程只是表示一個資源的擁有體,是不能執行的。要執行的話,一定需要一個線程。這也部分解釋了為什麼CreateProcess中為啥一定要傳入要執行的文件的名字。

而fork的含義是把進程本身CLONE一個新的出來。也就是說,FORK之後,父進程和子進程都執行同樣的一段代碼。如果想區分的話,可以根據FORK的返回值來區分。引用一段fork的說明:

On success, the PID of the child process is returned in the parent's thread of execution, and a 0 is returned in the child's thread of execution.

同時在Linux程序中,常見的寫法如下: int pid;
pid = fork();
switch (pid)
{
case 0: //I am the child

;
case -1: //failed.

;
default: //I am the parent


}


為什麼要這樣設計呢?因為Linux的設計目標之一就是應用於服務器。這種情況下,一個SERVICE可能會啟動很多進程(線程)來服務不同的CLIENT. 所以FORK設計成快速復制父進程。子進程直接使用父親的地址空間,只有子進程加載一個新的可執行文件的時候才創建自己的地址空間。

這樣節省了創建地址空間這個龐大的開銷,使得Linux的進程創建十分快。不過實際上,這裡的進程相對於Windows中的線程,所以同Windows中的線程創建相比,二者的開銷應該差不多。

那麼如何才能讓新的進程加載一個可執行文件呢,這時就要用execv以及相關函數了。所以Linux中,代替CreateProcess()的函數是fork+execv

Copyright © Linux教程網 All Rights Reserved