這是作業系統系列第 1 篇,
盡管作業系統發展史不是研究作業系統的重點,但是在這一發展程序中,衍生出了許許多多與作業系統相關的重要概念,如果知道這些概念出現在怎樣的背景下,以及產生的原因,在后期學習中就不會覺得一些概念出現的比較突兀,除此之外,了解作業系統的發展史,理解設計需求,有助于我們站在計算機的角度思考問題,
ENIAC 與串行處理
計算機的發展可以追溯到 1946 年,世界上第一臺通用計算機「ENIAC」 誕生在這一年的 2 月14 日(這天正好是情人節),

圖為 ENIAC
ENIAC 長 30.48 米,寬 6 米,高 2.4 米,占地面積約 170 平方米,30 個操作臺,重達 30 英噸,耗電量 150 千瓦,造價 48 萬美元,
從這一年一直到 20 世紀 50 年代中期,作業系統是不存在的,畢竟那時候還沒有作業系統這個概念,程式員要是想要運行什么程式,得把機器代碼用打孔機打在紙帶上(這不僅是個智力活,還是個要細心的活兒,打錯一個孔你就得重來,想象一下,讓你寫一篇文章,不用退格鍵,更不能從中間插入,,,當時的程式員太難了),然后通過輸入設備,比如紙帶閱讀機,載入計算機,計算機就按照步驟一步步運行下去,運行完畢,就把結果列印出來,
PS:這十幾年間,編程語言也有很大發展,這一階段后期就已經有高級語言——FORTRAN 了,編譯,鏈接,函式庫這些概念也已經實作,所以這一時間段的計算機不是你想象的那么落后!
這個時期,用戶如果有上機需求,就要提前預約一個時間段,然后才能去上機(往機器里放紙帶和控制機器的活也是他們自己來干,當個程式員你還得和硬體打交道),這樣的模式下,問題出現了:
- 如果用戶申請了 1 個小時,但他的任務只用 35 分鐘就運行完了,那多出來的 25 分鐘就這么被浪費掉了,
- 如果一個小時到了,用戶的程式還沒運行完,這個程式就會被強制停止——這相當于浪費了整整一個小時的計算資源,但延長時間是不可能的,后邊還有人排隊呢,而且萬一是你的程式死回圈了咋辦,
簡單批處理系統
在計算資源匱乏的當時,上面那種串行處理造成了巨大的資源浪費,令科學家們難以接受——必須要提高計算機的利用率,
于是,批處理系統誕生了,

圖為 IBM 7090,其上運行著最為著名的批處理系統 IBSYS ,這也是世界上第一款全晶體管計算機
批處理系統的中心思想就是用一個稱為監控程式(monitor)的軟體,剛剛提到了,串行處理需要用戶自己去訪問機器,時間段是固定的,但現在他們只需要把作業提交給計算機操作員,操作員會把這些作業按順序組織成一批,然后把整個批作業放在輸入設備上,供監控程式使用,
監控程式已經有點作業系統的意思了,它的的作業程序很好理解:
-
大部分監控程式總是常駐記憶體,這部分稱為常駐監控程式(resident monitor),
-
一開始,監控程式掌握了計算機的控制權(廢話,這時候用戶作業還沒加載進來呢),它會從輸入設備中讀取一個作業,經過讀入以后,作業就被放置在了用戶程式區域,并且獲得控制權,當作業完成后,控制權將再次回傳給監控程式,
有了監控程式后,計算機的利用率提升了——一道作業完成后立馬就會開始下一道作業,沒有任何空閑時間,也很少出現作業沒完成就被終止的情況(基本上解決了串行處理的問題),
監控程式的正確運行是依賴于硬體的,在這個時期,為了系統的可靠性,計算機廠商為計算機提供了幾樣重要的功能:
- 記憶體保護:這一點很好理解,監控程式的記憶體空間不能被用戶程式隨意更改——不管是有意還是無意,不過當時黑客這一群體還沒有發展,畢竟計算機又少又貴,不可能「飛入尋常百姓家」,一旦硬體檢測到有用戶程式試圖使壞,就會將控制權直接轉移給監控程式,取消這個作業,
- 定時器:這項功能是為了防止一個作業獨占系統,作業接管控制權后定時器自動打開,如果定時器時間到了而作業未運行完,程式會被殺掉,
- 特權指令:有的機器指令會被設定成特權指令(比如 I/O 指令),只能由監控程式執行,用戶程式是不能直接使用這些指令的,當然用戶程式可以請求監控程式為自己執行這個操作,特權指令就是為了限制用戶程式的「權力」而設定的,畢竟老板和員工不可能有一樣的話語權,

監控程式的記憶體布局,藍色部分就是受保護的記憶體區域
這幾種功能里,記憶體保護和特權指令引入了操作模式的概念,我們知道,現代作業系統中依然保留這兩種功能——足以見得他們的地位,
簡單批處理系統已經具備了基本的任務調度能力,但它仍有很大的改進空間,雖然簡單批處理系統為機器提供了一個自動作業序列,但處理器經常還是空閑的,因為 I/O 設備相對于處理器的速度要慢很多,處理器需要 I/O 操作完成后才能接著干活,
舉個例子:

CPU 利用率 = 1/31 = 3.2%
CPU 的利用率太低了,有什么辦法解決這個問題呢?
多道批處理系統

IBM System360,搭載了多道批處理作業系統 OS/360,公認的劃時代作業系統
我們剛剛說了,利用率低的主要原因就是 CPU 需要等待 I/O 操作,那我們讓 CPU 忙起來不就可以了?
多道批處理系統就是讓 CPU 忙起來的秘訣,方法聽起來很簡單——在記憶體里多放幾道用戶程式,一旦有一個作業需要等待 I/O ,就立刻切換另一個可能不需要等待 I/O 的作業,這種處理,稱為多道程式設計(multiprogramming)或多任務處理(multitasking),
我們來看看這種方法是怎么提高 CPU 利用率的:
- 圖 a :僅有程式 A 在運行

- 圖 b :記憶體上有用戶程式 A 和 B ,當 A 在等待 I/O 操作時,B 就開始運行,(為方便理解,我們假設 A, B 兩程式競爭的 IO 資源是不一樣的)

- 圖 c :用戶程式 A,B,C 同時存盤在記憶體上,

我們可以直觀的看到,在同樣的時間內,CPU 運行時間大大提升,滿足了我們的預期,
像簡單批處理系統一樣,多道程式批處理系統必須依賴于某些計算機硬體功能,其中最顯著的功能就是支持 I/O 中斷(Interrupt)和直接存盤器訪問(Direct Memory Access,DMA),(DMA 也需要中斷的支持)
中斷這個詞,第一次聽會感覺有點玄乎,如果翻譯成「打斷」感徑訓好理解一點(就是不大好聽),當一個作業開始進行 I/O 操作時,CPU 就會切換到另一項作業,那作業系統怎么知道這個 I/O 操作什么時候結束呢?
答案就是 I/O 中斷,在 I/O 操作結束后,DMA 模塊(哪種模塊具體取決于系統實作)就會向 CPU 發送一個信號,CPU 就必須停下當前的事情去處理這個信號,在多道批處理系統里表現為控制權被轉移到作業系統的中斷處理程式,這個程序,就是 I/O 設備打斷(Interrupt)了 CPU 手頭上的事情,轉而去做另一件事,
所以說中斷是作業系統完成各種復雜操作的前提,
多道批處理系統顯然比他的前輩們復雜多了,由這個作業系統,又引申出來了幾個比較有意思的話題:
- 作業管理:記憶體的空間是有限的,意味著一次性載入到記憶體的程式數量也是有限的,那么怎樣從備選作業里選擇合適的作業加載進記憶體就是一個問題,這就是就是作業管理,
- 記憶體管理:選擇了作業,就需要為作業分配空間,那從空閑區的哪一部分為作業劃空間就是記憶體管理需要解決的事情,
- 行程調度:行程,就是進行中的程式,一般我們把加載進記憶體的作業稱為行程,以和未加載的作業區分,行程調度,就是當需要進行行程切換時,通過某一種演算法從行程佇列中取出合適的行程,獲得 CPU 的執行,
到了現代,因為記憶體容量的提升,很少出現有作業需要在后臺排隊的情況,所以作業管理以后只會花少量筆墨來介紹,但記憶體管理和行程調度將是我們以后學習的重點,
分時系統
UNIX 就是最為著名的分時作業系統
多道批處理系統可以說是現代作業系統的雛形了,它處理批作業時對處理器的利用率也比較令人滿意,但面對多個互動作業,多道批處理系統就顯得力不從心了,
互動作業的出現很好理解,畢竟我們現在幾乎所有應用程式都是互動式的,你滑動螢屏,這篇文章就會上下滑動,點一個分享,就會出現各種選項,等等等等,
在互動作業中,難免需要等待用戶做出操作,但又不可能讓處理器停下來等你一個人,畢竟很多人都在用同一臺計算機,因此分時系統應運而生,
顧名思義,分時系統就是 n 個用戶作業,作業系統控制每個用戶程式以很短的時間為單位交替執行,因為人的反應相對機器要慢很多,所以如果控制得當,你會感覺自己是獨占了這一臺計算機一樣,
多提一句,分時系統切換行程靠的就是我們在批處理系統中強調的中斷,不一樣的是,這里的中斷是時鐘中斷——一到時間就向 CPU 發出中斷信號,
如果把多個用戶運行的互動程式,看做一個用戶運行的多個互動程式,像我們現在使用個人計算機一樣,就很容易理解現代作業系統了:
- 多個行程共用一個處理器,每個行程分得一個時間片,而在計算機面前的你看來,好像多個行程是并行的,
- 某行程進行 I/O 操作會被作業系統阻塞,在阻塞佇列等待 I/O 操作結束,才能有機會使用 CPU,
- 多個行程在記憶體上存盤,作業系統需要防止行程向其他行程的記憶體空間寫入資訊,尤其要保護作業系統自身的記憶體空間,
- 用戶程式運行在用戶態,無權使用特權指令,需要向作業系統提出請求,
講到這,我們已經了解了作業系統的發展,事實上,還有一些其他的作業系統,比如實時作業系統,網路作業系統,分布式作業系統等等,但這些作業系統與我們生活相關性不大(實時作業系統對嵌入式來說還是很重要的),所以在此文略過,有興趣的可以查閱相關資料,
希望在閱讀完這篇文章之后,你能夠對作業系統的設計理念有一個簡單的印象,如果本文引起了你對作業系統的興趣,那就再好不過了,
感謝你的閱讀,我們后會有期!
宣告:原創文章,未經授權,禁止轉載
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/71538.html
標籤:C
上一篇:C語言指向函式的指標
下一篇:C語言入門-回圈
