01 作業系統都學些什麼
作業系統的重要性當然不止於此。如果深入研究你就會發現,作業系統在整個計算機學科體系中處於一個十分關鍵的位置。計算機科學的學科方向多如牛毛,但總的來說可以分成兩塊,硬體一塊,軟體一塊,這兩大塊都喜歡各玩各的,中間說是隔著次元壁也一點不誇張。
但都在一個體系內,總要想個辦法來打破次元壁呀,這個重要的工作由誰來做呢?就是作業系統。所以從體系架構的角度看,操心繫統是處在所有硬體的最上層,和所有軟體的最下層,是一個“跨界”的角色。
作業系統很重要,那作為一門學科,難不難學呢?大家的態度走兩個極端,一邊的人覺得作業系統有什麼可學的,不就是點滑鼠劃玻璃,太簡單連小學的計算機課都不一定認真教,大學還專門設了專業課太誇張了。另一邊的人又覺得作業系統太難,作業系統的玩家不是Linus這樣的業界大神,就是微軟、谷歌這樣的行業大佬,萌新小本只好瑟瑟發抖。
這些觀點對不對呢?
都有一些理解上的偏差。我們平時常說的“安裝作業系統”,這裡的“作業系統”,準確來說,應該叫“作業系統產品”,而作業系統這門課,主要內容講的是作業系統的核心原理。
作業系統產品和作業系統核心二者的關係,有一點像計算機和CPU,沒有它不行,光有它也不行。一款作業系統產品,首先肯定得有作業系統核心,但是光有核心是沒法使用的,還得加上配套的周邊功能。
雖然叫“周邊配套”,但絕不是可有可無的意思,大部分我們所熟識作業系統功能,實際上都是屬於“周邊配套”,譬如說我們最最最熟悉的“桌面”,放著漂亮的桌布,擺滿各色各樣的圖示,是作業系統主要的使用者互動介面,術語稱為圖形使用者介面(Graphical User Interface,簡稱GUI)。
前面感覺自己“精通作業系統”的那位同學,其實精通的只是GUI的使用,而且很抱歉,GUI不在作業系統核心裡面。
不過,話說回來,雖然專門有“作業系統核心”這樣的術語,但並不意味著所謂的“核心”與“周邊”之間,天然就存在一條清晰的界限。在作業系統裡面,一直存在著宏核心和微核心兩條路線的爭論,爭論的焦點,正是什麼該劃入“核心”,什麼又該算作周邊。
微核心的主張,顧名思義,就是最小化核心所需要提供的服務,只負責最基本的功能,把應用服務、驅動、GUI,甚至一些感覺上也挺基本的功能,譬如檔案系統服務,都統統趕出核心。
這樣做的好處是靈活方便,像是要提供新服務,那直接新增就可以了,不需要對核心進行額外的改動,但缺點也很突出,什麼功能都趕出去了,真到用的時候還需要進行核心模式-使用者模式的切換,模式切換會增加額外的開銷,導致效能受損,因此就有人主張應該把常用的功能都接納進來,這就是宏核心。
Windows早前採用的就是微核心架構,把GUI趕了出去,結果效能損失受不了,後來又重新請回來,一直到現在,GUI仍然是Windows核心的一部分。
02 作業系統的核心內容作業系統這門課主要研究的是作業系統核心,這名字不太平易近人,容易給人“難學懂”的感覺。確實,現在作業系統的功能越來越豐富,連帶著作業系統核心也越來越複雜。有一本作業系統業內很有名的書,叫《Windows Internals》,講的是Windows作業系統的功能原理,從這本書就可以看出來作業系統的一個變化趨勢。
《Windows Internals》是跟著Windows推陳出新的,Windows不斷更新,這本書也不斷再版,一個肉眼可見的變化就是書越寫越厚,現在最新版乾脆把一本書分成了上下兩卷,內容太多,光一塊磚頭已經不夠裝了。
這還只是Windows,現在是移動網際網路時代,還有作業系統還有一半多的江山被iOS和Android這哥倆佔著,而且都以一年一個版本的速度迭代,要學的知識豈不是漫無邊際?
其實不用擔心,作業系統確實在迅速發展,但最最核心的還是那些老兄弟。作業系統有一本非常經典的教材,只要你問就一定會有人推薦,叫《Operating System Concept》,中文譯為《作業系統概念》。因為這本書的封面畫著恐龍,所以學界也稱為“恐龍書”。
恐龍書不但介紹作業系統知識,還會引入“當前主流作業系統”作為研究案例。當然,恐龍書已經從第1版發展到了第9版,書裡的“當前主流作業系統”也一換再換,默默地記錄著作業系統的變化發展。
不過,我把幾個版本比較了一下,最新版知識點增加了不少,還補充了一些新的內容,涵蓋了iOS、Android等移動作業系統,但主要的知識結構並沒有大幅調整,核心的研究物件和問題,仍然是早就登場的那幾個。
具體是哪幾個呢?就仨:程序、記憶體和儲存。作業系統最重要的功能就是“管理”,具體來說是兩項工作,資源的分配和資源的排程,那管理的核心物件是哪些呢?就是這仨,分別對應的硬體是CPU、記憶體和硬碟,想想就能知道,這仨同樣是計算機裡的三個扛把子部件。
我們說恐龍書經典,其中一個地方就體現在對作業系統知識體系的劃分上面。恐龍書當然會重點照顧這三個核心物件,為它們一一設有單元,再加上必不可少的概論、大家現在都很關注的安全,以及前面提到的案例分析,就構成了恐龍書最新第9版的六大知識板塊。
作為一名作業系統愛好者,我看過很多作業系統的書,有偏重原理的,有偏重例項的,也會有其它新的偏重,譬如會為網路,硬體架構、裝置管理等等內容設定獨立章節,但無論哪本書,程序、記憶體和儲存(也有稱為外存)始終是書裡的三條主線。總而言之,學作業系統,首先都得緊緊抓住程序、記憶體和儲存學懂學通。
03 怎樣學作業系統既然程序、記憶體和儲存是作業系統的三個核心物件,那具體應該怎麼學呢?一句話回答:帶著問題學。這裡的“帶著問題學”,和我們平時常說的有所不同,在作業系統裡面,程序、記憶體和儲存都有各自需要重點關注的問題。
就拿程序來說,程序是作業系統中相對比較抽象的概念,所以大多數作業系統的教材都會不吝筆墨,給程序下一堆的定義,試圖只靠文字就解釋清楚什麼是程序。不過效果總不太好,大家不容易看懂,還容易看暈,畢竟“抽象”的意思就是說,你懂了馬上心領神會,你不懂總感覺雞同鴨講。
我倒認為沒必要在程序的定義上作過多糾結,關鍵是功用,開始只需要記住一點,程序對應的是CPU。計算機所謂的“計算”,指的就是CPU運算,那運算什麼內容呢?這就是程序。
本來這個過程不算複雜,好像也沒什麼問題,但是後來人們搞出了“多程序”,一個CPU能“同時”執行多個程序。但這個“同時”不是真正的同時,用術語來說,是併發執行而不是並行執行,結果一下就複雜起來,問題也就隨之而來了。
程序增多了,但CPU卻只有一個,出現了多對一的競態問題,這就是一切問題的起源。圍繞著競態問題,程序接著又衍生出了許多問題。
首先就是排程問題。對作業系統來說,排程是個大問題。書本肯定都會告訴你,程序有很多個狀態,有些還畫成了狀態遷移圖,各種線飛來飛去,看得眼花繚亂。感覺上很難,但我覺得,把握好了背後的邏輯,這些看似凌亂的知識點就是條理清晰地串在一起。
在這裡,我們只需要死死盯住競態問題,正是因為程序和CPU不再是一一對應,所以需要排程,而所謂排程,就是雜技裡的用兩隻手玩五隻球,總會區分出接回手裡的、準備丟擲的和停在空中的幾種情況,所以也需要根據情況給程序配套設計不同的狀態,排程的具體工作,就是想辦法讓程序在這幾個狀態中來回遷移倒騰,最終營造出CPU同時執行多個程序的假象。
程序之下是執行緒,現在又搞出了協程和纖程,以後不知道還會什麼程,不過,目的只有一個,更充分地利用CPU時間,而且都難以避免一個問題,就是排程問題。
排程本身不難,難就難在設計排程原則,誰上誰下,執行多久,等待多久,都需要一一加以考慮,而且最難的地方在於,排程是沒有最優解的,只有在指定原則條件下,設計出相當不錯的排程方案。
程序除了競爭CPU,還要競爭資源,譬如兩個甚至更多的程序可能都需要同時讀寫同一個檔案,我們熟悉的多對一的關係,會導致我們熟悉的競態問題,在CPU那導致了排程問題,而到了資源這裡,則會導致同步問題和死鎖問題。
同步問題很簡單,程序既然要排程,那肯定沒辦法把活一口氣幹完,譬如說讀寫某個檔案,讀到一半被換下來了,下次再換上來的時候發現,別的程序也在讀寫這個檔案,內容變了。
多執行緒有一個默契,就是前後環境要保持一致,你把我從CPU那換上換下我沒意見,但你得保證我所處的環境是相同的,別像雍正那樣一覺醒來發現大清亡了,後面也就沒法跟著劇本走。那怎麼保證一致性呢,這就是同步問題,方法包括互斥鎖、訊號量等等。
死鎖問題聽起感覺複雜一點,書上花了不少筆墨但內容還是不好懂。其實也不復雜,我們在小區門口喜聞樂見的堵車就是死鎖。小區門口只有一條車道,早高峰大家都得排著隊出去,這時如果外面有一輛車回來,開到門口又不肯避讓,那就堵車了,用作業系統的術語來說,就是死鎖了。
前面說,為了解決同步問題,我們會採取互斥鎖等方法,簡單來說,當多個程序都要使用同一項資源時,只有當前正在使用的程序用完了,也就是術語所說的資源釋放了,後面的程序才可以接著用。這樣做的好處當然是保證了一致性,但壞處則是導致了另一個問題,就是死鎖問題。
拿前面的小區出口比劃一下就清楚了。單車道當然是互斥的,要麼只進要麼只出,不可能一邊進一邊出。如果兩頭的來車各佔一半車道,結果當然是想進來的進不來,想出去的出不去,兩頭堵死,這就死鎖了。
那怎麼解決死鎖問題呢,大方向有兩種,一種是避免出現死鎖,從根本上解決這個問題,不過難度較大。另一種則是想辦法對已經發生的死鎖及時檢測發現,然後進行恢復。但是怎麼才能及時發現死鎖呢?這又是一個作業系統方向需要研究的問題。
延伸閱讀《現代作業系統:原理與實現》
推薦語:作業系統和系統安全領域國際知名學者、上海交通大學陳海波、夏虞斌領銜撰寫。作者在復旦大學和上海交通大學十餘年作業系統教學經驗的科學總結。由淺入深介紹現代作業系統經典理論與方法,結合前沿研究與工業界實踐,面向真實場景與真實問題。全新打造ChCore微核心系列課程實驗,建立對作業系統的第一手實踐經驗。