面試總結-OS篇(windows與linux內核對比)
原創 2012年05月07日 22:14:07
首先明確操作系統的幾大模塊:
1. 系統初始化
2. 進程管理
3. 文件系統
4. 存儲系統管理
5. I/O管理
那麼windows內核和linux內核在這幾個模塊上有哪些相同之處呢?又有哪些不同之處呢?
首先,作為os,他們的理念都是相似的。
1. 一切皆文件。 可能讀寫文件很好實現把,linux不管修改個什麼東東其實都是在修改文件
2. 進程是執行的實體。 幾乎對於操作系統的一切操作,都要通過進程來實現的,這個才是管理資源的真正實體。
3. 中斷。 在西電學習時,劉西洋做過這樣一個比喻。一個操作系統其實就是一個主循環加中斷,我覺得其實還是蠻生動的,很能突出中斷對於整個操作系統的意義。
下面,對於windows和linux做一個簡單的評析,以及提出一些在面試中遇到的問題,估計也是實際開發中的問題,內核之間肯定還是有不小區別的。
定位:windows vs linux
眾所周知,windows是商用系統,面向大眾的。既然是商用的,商用的很大一個特點就是向後兼容。而linux是開源系統,內核之間的升級很多時候並不兼容,主要是為了加入更多更新的東西把,但是升級真的很麻煩。
其次,windows只是pc領域的霸主,而linux在設計之初,很多時候是針對伺服器的。這個也導致了他們在實現的很多區別。
系統初始化:
略。不是很關鍵吧。但是實現過程都應該差不多,有興趣大家可以去查下。
進程管理:fork+exevc vs createProcess
Linux的進程創建函數?當然是fork了。Linux中進程本身是可以執行的。在windows中,進程只表示是資源的擁有者,不能單獨執行,執行必須要一個線程。
fork()的含義是把進程本身clone一個新的出來。也就是說,fork之後子進程和父進程都執行同樣的一段代碼。想要區分,必須通過fork的返回值來區分。
int pid = fork();
if (pid < 0) {// printf("error");} //小於0,發生錯誤
else if( pid == 0 ) {// printf("子進程!");} //==0,為子進程
else{ // printf("父進程! ");} // >0,父進程
為什麼這個樣子呢?Linux主要應用於伺服器。而伺服器最多用到的是把同一個資源開闢很多個進程給n多個用戶來同時使用啊。這樣開銷夠小,響應夠快。所以fork快速複製父進程,子進程直接使用父進程的地址。那麼子進程需要執行其他的資源呢?用exevc族,這個時候才為子進程開闢自己的地址空間,傳入需要執行的文件,就可以執行具體的內容了。
而windows中,createProcess有一大堆的參數,不過很多時候都默認為null。它的作用相當於fork+execv吧。
那麼怎麼理解linux和windows下的進程管理呢?
一個進程最基本的內容:PCB、程序段、數據段
一個線程包含的內容:線程ID,當前指令指針(PC),寄存器集合和堆棧組成。
線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。
資源在外存上時候,往往都是代碼、資源什麼的,就是程序本身。而在內存上的時候,就有了進程,進程相當於代碼的一次生命周期,準備了一些最基本的能為運行做準備的上下文情況。而進程總要在cpu上跑一次把,執行一條一條的指令,這個時候就是線程在管理,線程相當於進程的一次生命周期,它真正的活了一把啊。
那麼os在執行時,就是進程線程都要準備好的。而linux在實現的時候,其實相當於是新建了很多指針指向同一塊資源,能夠直接給你執行,在運行時大家都控制處理它,夠快吧。而在需要執行不同的文件內容時,才為他在內存中分配相應的內存空間,做個替換工作,就有新的實體了。而windows下進程是資源的擁有者,你們誰想用就新建個線程自己去跑吧。
文件格式:PE vs ELF
windows可執行文件格式是PE(portable and executable,可攜帶可執行)。而linux使用的ELF(executable and linkable format,可執行和可鏈接格式)。兩者都有相似的東西,比如都分成了幾個section,包括代碼段,數據段等。但是兩個又不一樣。
由於windows內核固定,而linux內核之間往往不兼容。linux軟體安裝問題往往讓人很抓狂。在windows中只需要next、next一步步繼續就好了,而linux的軟體包則有很多,.deb、.rpm、.tar.gz什麼的。而內核版本不固定帶來的效果是可以升級很快,但向後兼容問題則讓我們抓狂的要死。安裝過程往往需要更改軟體依賴關係什麼的!!!Oh, fucking linux。而這些內核理念上的不同很大程度上導致了他們文件格式的不同。
文件系統:ntfs vs ext2&ext3
NTFS 提供長文件名、數據保護和恢復,並通過目錄和文件許可實現安全性。NTFS 支持大硬碟和在多個硬碟上存儲文件(稱為卷)。例如,一個大公司的資料庫可能大得必須跨越不同的硬碟。NTFS 提供內置安全性特徵,它控制文件的隸屬關係和訪問。從DOS或其他操作系統上不能直接訪問 NTFS 分區上的文件。如果要在DOS下讀寫NTFS分區文件的話可以藉助第三方軟體;現如今,Linux系統上已可以使用 NTFS-3G進行對 NTFS 分區的完美讀寫,不必擔心數據丟失。
Ext2是 GNU/Linux 系統中標準的文件系統,其特點為存取文件的性能極好,對於中小型的文件更顯示出優勢,這主要得利於其簇快取層的優良設計。
Ext3是一種日誌式文件系統,是對ext2系統的擴展,它兼容ext2。
1、高可用性
2、數據的完整性
3、文件系統的速度 儘管使用ext3文件系統時,有時在存儲數據時可能要多次寫數據,但是,從總體上看來,ext3比ext2的性能還要好一些。這是因為ext3的日誌功能對磁碟的驅動器讀寫頭進行了優化。所以,文件系統的讀寫性能較之Ext2文件系統並來說,性能並沒有降低。
4、數據轉換 由ext2文件系統轉換成ext3文件系統非常容易
5、多種日誌模式
比較:從技術而言,windows在做這些方面真的很不入流。它對文件系統的以及設備的管理遠遠不及linux,windows下的刷新鍵不知道毒害了多少人呢?
Linux可以同時管理幾千個處理器,windows呢?兩個都夠嗆。Linux連續使用很多天,使用越來越快,windows一會就不行了。Linux的文件使用越多碎片就越少,windows一會就卡的要死。
中斷與I/O:
1. 中斷是由非同步的外部事件引起的。外部事件與中斷響應及中斷響應與正執行的指令沒有關係
2. 異常是執行指令器件檢測到不正常的或非法的條件引起的。異常與正執行的指令有直接的聯繫。根據引起一場的程序是否可被回復和恢復點不同,把異常分為故障(fault)、陷阱(trap)和中止(abort)。
故障是在引起異常的指令之前,把異常情況通知給系統的一種異常。
陷阱是在引起異常的指令之後,把異常情況通知給系統的一種異常。
中止就是中止處理了
Windows中IRQL(Interrupt ReQuest Level)的概念,而linux中沒有。
一個常規的IRQL如下:
31:高 30:掉點 29:處理器間中斷 28:時鐘 27:配置文件 26 。 。 。 3:設備中斷(其實只用了16個) 2:DPC/調度 1:APC 0:無源
Windows中有32級,而linux中似乎只有5級。更多的優先順序可以使響應各級服務時更加的好,但是嵌套深度太多總是容易帶來一些不必要的麻煩。
相似之處:
都將中斷分為了兩部分。在LINUX中叫ISR(還是其他?)和BOTTOM HALF。而WINODWS中,DPC(Deferred Procedure Calls)和APC(Asynchronous Procedure Calls)就非常類似BOTTOM HALF。
以linux為例:
上半部響應中斷,下半部分為中斷處理函數。
下半部分處理機制有tasklet、工作隊列、軟中斷
一. 軟中斷 軟中斷是靜態分配的,這也就意味這如果想定義新的軟中斷就必須重新編譯內核。軟中斷可以並發的運行在多處理器上,即使同一個軟中斷也是這樣。所以,軟中斷函數必須是可重入函數,而且需要使用自選鎖來保護數據結構。
二. tasklet tasklet也是一種軟中斷,但是tasklet比軟中斷有著更好的並發特性。是io驅動程序首選的可延遲函數方法。tasklet有如下的特性: (1)tasklet可以在內核運行的時候定義 (2)相同類型的tasklet不能在用一個CPU上並發運行,也不能在不同的CPU上並發運 (3)不同類型的tasklet不能在同一個CPU上並發運行,但是可以在不同的CPU上並發運行。所以如果不同的tasklet訪問相同的數據結構,需要加一定的鎖保護
三. 工作隊列 工作隊列由內核線程來執行。主要的數據結構是workqueue_struct結構。這個結構是是一個cpu_workqueue_struct的數組。cpu_workqueue_struct結構是工作哦隊列的基本結構。主要有此工作隊列工作的鏈表,還有內核線程的進程描述符的指針。 工作隊列的工作是由work_struct結構組成,這個結構有需要執行的函數,以及傳輸的數據等欄位。建立工作隊列是一項非常耗時的操作,因為它會建立一個內核線程。所以linux默認建立了一個工作隊列來供使用。每一個CPU一個這樣的工作隊列。
管理:
註冊表
這個是windows特色,而linux中每個軟體有自己的配置文件即可,靈活性很大
軟體使用
其實windows下的軟體絕大多數都有linux的對應東西。比如說word,在linux下使用latex做出來效果往往非常只好,而且不會因為移植問題二格式發生變化。用vim與ide相比呢?其實什麼軟體最好,當然是diy的了,定製的總是最好的咯
如何深入內核: shell?(常用命令)
Linux很多時候通過shell來訪問內核,命令行模式為在經常接觸內核的過程中算是個很好的選擇了。總比windows下用資源瀏覽器或者ie總出現未響應要好得多吧。
內核樹與補丁?
其實就是內核源碼
Linux內核開發流程當前包括一些主內核分支,和很多不同的子系統專有的內核分支。它們是:
- 主 2.6.x 內核樹- 2.6.x.y -stable 內核樹- 2.6.x -git 內核補丁- 2.6.x -mm 內核補丁- 子系統專有內核樹和補丁理念:
補丁? 真想不通windows為什麼那麼麻煩,有缺陷通過打補丁的方式,還不斷的更新。有病毒買殺毒軟體花錢,整理系統花錢,什麼都花錢,費勁。
內核為何使用了C,而非C++?
根據linus torvalds的解釋:C++語言想解決的問題都不對路,都是一些皮毛問題,而沒有涉及真正深層次的問題。 C++的對象、模板和函數重載都基本上純粹是C的語法擴展,是語法糖,總體上把C的語法和類型系統都弄得更糟。他建議,在系統編程里直接用C就可以,非系統編程里,應該選擇一種有垃圾收集的語言,C++語言的特性基本無用,只會搗亂。因此,什麼時候C++都不可能是正確的選擇。
Linus也承認,在其他一些情況下,可能需要更多語言支持,語言級的內存分配機制如垃圾收集、並發、動態代碼生成等等。但是內核開發不需要。
很多時候c++的stl、boost庫都已經很成熟了,但是都有一定的編程模型什麼的在裡面。但是在對內核進行更改的時候,這些東西很可能讓內核更改陷入困境。簡潔就是美吧,抽象程度太高在某些時候未必奏效吧!!!
面試中常見OS問題:
進程與線程區別?線程安全?
進程狀態切換?
死鎖?死鎖條件?
創建進程、子進程?
常見linux命令?
中斷?Windows下linux下的區別?
IPC?那兩大類?主要的ipc方式?
Linux建立工程編譯等問題?
Linux編譯內核?內核移植?
Socket編程?
Gdb調試程序?Makefile熟悉?
驅動開發熟悉否?編寫驅動?
。。。
大概就這些吧,當年面了很多嵌入式崗位,現在又刪了些,感覺不要當年還是挺喜歡總結的,寫的不好,將就著看吧
推薦閱讀: