天天看點

作業系統的理念—以windows和linux為例

linux的線程和程序并不區分,其實這完全是設計思想造成的,在linux中,其樸素地繼承了unix的思想,就是“任務”代理使用者操作“資源”,這裡的任務就是程序,而資源就是檔案,unix為了純樸的不做作的實作這個思想,是以才有了一切皆檔案的設計同時程序的意義也明顯起來。而在windows中,它面對的是豐富的使用者應用而不僅僅是為了操作一些資源,比如可以看電影,可以玩遊戲,可以...這一切使得還按照使用者/程序/資源的大粒度設計變得十分不合适,對于面向豐富使用者應用的windows來說,使用者不是那麼“專業”,當然其需求也就不那麼“專一”,是以必須按照更細粒度的“對象”來作為基準設計系統,是以,在一切皆對象的windows裡面,建立程序和建立線程是兩碼事,因為它們是不同的對象(在linux中,它們都是任務的元素)。記住,在linux中,其根本就是任務代理使用者實作資源通路,而在windows中其根本就是對象的任意組合實作使用者的任意需求。前面的文章不是說linux是小粒度的嗎,這裡怎麼顯得windows的粒度更小啊,其實linux的小粒度第一是程序層面上的,第二就是核心元素層面上的,其優勢就是使擴充變得靈活容易,而且可以通過組合低消耗地完成巨大任務(注意任務巨大不一定需求複雜,這也就是linux和windows的根本不同之所在),而windows的小粒度就是對象化,這個優勢決定了windows很容易實作使用者的需求。在《漫談相容核心》系列文章中有這麼一句話:程序在兩個系統中的地位與權利有很大差別。在 Linux 中每個程序都有相當的獨立性,有自己的“隐私”和“私有财産”,而在Windows 中一個程序甚至可以替另一個程序建立一個線程。其實想一下就知道這其中的緣由了,畢竟windows就沒有把程序當成什麼大不了的東西,它就是一個普通的對象,和檔案簡直沒有什麼本質的差別。不妨類比一下軍事要塞和一個舉行Party的禮堂,對于軍事要塞,職能單一但是功能強大并且對于通路嚴格控制,閑人免進,而對于禮堂,大家亂作一團,瘋狂暢飲,不亦樂乎,制定嚴格的制度隻會擾亂氣氛。 

對于排程,兩個系統仍不相同,linux的排程器是一種水準的結構,就是排程task_struct,而windows的排程卻是一種階層化排程,在排程線程之前要先參考其所在的程序的優先級。但是linux的程序/線程統一化設計也有自己的優點,如果你為一個機制設計兩個實體,那麼在政策上你就要考慮兩個實體,包括它們的互斥,它們的協作等等任何它們之間的互動,然而你隻設計一個實體,那麼你就可以少考慮很多事情,更加專注地解決需要解決的邏輯,對于linux來說,用task_struct很容易的就可以實作那種分層的階層化排程,而且不同于windows的整體化的嚴格的必須的分層排程,在linux中,這種分層排程隻是排程器的一個政策而已,這就是分組排程,在2.6.25核心得到了增強。在windows中在排程一個線程運作前,必須參考其程序的優先級,這是它的程序/線程分離設計導緻的,而對于linux,你想實作任何方式排程隻需要給排程器寫一個政策既可,排程器為外界提供了排程類,排程組等容器以及一系列的政策設定接口,你想讓排程器怎麼排程都行,你想實作windows的方式,那麼好辦,你把所有的屬于一個程序的線程放到一個排程組中,然後讓排程器分組排程,排程器的分組排程還可以嵌套,層層向上,比如你可以把程序的所有線程作為一組,稱組1,然後一個使用者的一個類别的程序的所有組1組成組2,然後按照使用者組成組3...這種政策很不錯,而且依據排程器提供的接口,你還可以做出更好的排程政策。在排程器看來linux的task_struct可以有多種拓撲結構,如果是一個連結清單,那麼就是水準的排程,也就是task_struct的優先級比較然後排程(比如O(n)或者O(1)或者非組方式的cfs),如果是一棵樹和簡單圖,那個就是分組排程了,根據樹的高低可以看出組的深淺,你當然可以實作自己的政策使排程器把所有task_struct看成一個圖或者一張表,這隻是政策實作問題,在windows的排程器看來,所有的線程就是一個連結清單,然後指向它們的程序,程序也是一個連結清單,是以排程器看程序和線程就是一張扁平的圖。那麼除了排程器,别的核心管理機制會看到程序/線程的什麼樣的拓撲結構呢?衆所周知,linux的fork機制可以像細胞分裂一樣建立一個又一個新程序,而windows卻不是這樣的。fork機制讓人覺得程序(當然還有線程)們最終會組織成一棵樹,比如用pstree可以看到,但是那隻是導出給使用者的拓撲結構,在核心中其實程序們是一張網狀的圖,因為各個同級别程序之間會通過連結清單聯系,比如兄弟程序之間的關系,其實在windows中雖然不是fork機制建立新程序,然後也是一張網狀圖的程序拓撲結構,因為這樣容易定位和管理程序,畢竟作業系統再不把程序當回事,也要有程序管理這一塊,windows的程序網和linux的程序網所不同的就是linux的網鋪開的廣度可能更大些,而windows的可能會是扁平狀。 

回到前面讨論過的問題,unix/linux的本質是任務代理使用者通路資源,然後unix把資源統一成了檔案這個概念,最終像套接字,管道都成了檔案,于是程序作為任務在核心的資料結構,裡面必然要有一個表示檔案的結構數組,每一個元素代表程序使用的一個檔案,這個結構就是打開檔案表,對于windows而言,檔案并沒有被特殊抽象出來,因為沒有必要,在windows中,一切都是對象,而且每個對象屬于一個類别,實際上每一類對象都代表了一個現實中的實體,比如程序,線程,信号量,檔案...windows的本質就是靠這些對象自身的協作滿足使用者需求而不是通路資源,可是不知道是曆史原因導緻作業系統理論已經成型還是這麼實作不用自己發明輪子進而更簡單,windows還是将程序/線程作為了執行任務的使用者代理實體,程序作為容器,線程作為執行緒,于是在程序這個特殊的對象裡面必然需要描述所有被這個使用者代理使用的對象,這就是程序的對象句柄表,表中的每一個元素代表一個該程序使用的對象,類比在linux中的統一的檔案資源架構,隻要獲得一個檔案的通路權限,那麼任何程序都可以通路,反過來到了windows中,檔案統統被對象替代,同樣的,隻要獲得了對象的通路權限就可以通路該對象,有什麼錯嗎?沒有!是以,對象的安全描述符才那麼重要,是以,windows中才實作了基于角色的複雜的通路控制機制,是以,才有了跨程序建立線程等機制,對象間互訪而已!

 本文轉自 dog250 51CTO部落格,原文鍊http://blog.51cto.com/dog250/1274145接:

繼續閱讀