02.操作系統概述.md

2. 操作系統原理介紹

這篇文章主要想從基礎介紹一下操作系統是如何運行的,主要專注於操作系統是如何對應用程序進行調度的。需要有前一篇文章作爲基礎

2.1 操作系統的目標和功能

2.1.1 作爲用戶/計算機接口的操作系統

  一個應用程序可以使用一種語言開發,如果沒有操作系統的話,每一個開發者都需要十分了解計算機的硬件指令纔行,這是不可想象的。操作系統做了一層抽象,就像開發應用程序的時候會寫的各種工具類一樣,操作系統對這些部分的操作提供了封裝的模塊,應用程序只需要調用就好了。
  同時還有一些通用的工作,比如創建程序,管理文件,控制io設備等,操作系統對這些操作都做了封裝來簡化編程。
下面是操作系統面向開發者或者用戶的一些功能

  1. 程序開發:指一些輔助的應用程序開發工具
  2. 程序運行:運行一個程序需要很多不住,必須吧程序加載到內存當中,初始化io設備和文件,準備一些其他資源,操作系統爲用戶處理這些調度問題
  3. io設備訪問:每個io設備都有自身的指令集或者控制信號,操作系統屏蔽了這些差異,程序員可以使用簡單的讀寫操作來對這些設備進行訪問
  4. 文件訪問控制:對文件的訪問不僅需要了解對應的磁盤存儲設備的特性,還要了解文件的數據結構,同時有時候還要進行訪問權限的控制,這些都由操作系統來完成
  5. 系統訪問:操作系統控制對整個系統的訪問(內存,io等)
  6. 錯誤檢測和響應:存儲錯誤,算術溢出等故障都是由可能出現的,操作系統需要對這些錯誤能夠響應這些異常並記錄或者報告
  7. 記賬:記錄各個資源的使用率數據

2.1.2 作爲資源管理器的操作系統

一臺計算機就是一組資源,這些資源用於移動,存儲和處理數據,並對這些功能進行控制,操作系統負責管理這些資源。

2.2 操作系統發展簡史

  計算機的發展經歷了無操作系統(串行處理),簡單批處理系統,多道批處理系統,分時系統通過對這些原理的學習,更加明白了計算機是如何運行的。解開了進程,線程等等後面的迷霧。
可以參考這裏 進一步瞭解

2.2.1 串行處理

  這個時候是沒有操作系統,程序員需要直接與計算機硬件打交道。這些機器在一個控制檯上運行,包括 顯示器,指示燈,觸發器,某種輸入設備和打印機。
  用機器代碼編寫的程序通過某種輸入設備(如卡片閱讀機)載入計算機。一個錯誤使得程序停止的時候,某個指示燈亮。如果程序正常完成,輸出結果將出現再打印機中。
  這種系統的劣勢不言而喻,在程序運行前的準備工作量非常大。如果用戶申請了 1 個小時,但他的任務只用 35 分鐘就運行完了,那多出來的 25 分鐘就這麼被浪費掉了。

2.2.2 簡單批處理系統

  爲了提高利用率,人們有了開發批處理系統的想法。批處理系統的中心思想就是用一個稱爲監控程序(monitor)的軟件。剛剛提到了,串行處理需要用戶自己去訪問機器,時間段是固定的,但現在他們只需要把作業提交給計算機操作員,操作員會把這些作業按順序組織成一批,然後把整個批作業放在輸入設備上,供監控程序使用。
監控程序已經有點操作系統的意思了,它的的工作過程可以從下面兩個角度理解:

2.2.2.1 從監控程序的角度來看

  一開始,監控程序掌握了計算機的控制權,爲了做到這一點,大部分監控程序總是常駐內存,這部分稱爲常駐監控程序(resident monitor)。
  其他的部分,包括一些實用程序和公共函數,他們作爲用戶程序的子程序,在需要他們的作業開始的時候纔會被載入。
  監控程序會從輸入設備中讀取一個作業,經過讀入以後,作業就被放置在了用戶程序區域,並且把控制權交給這個作業。當作業完成後,他將控制權再次返回給監控程序。監控程序立即讀取下一個作業。每個作業的結果被髮送到輸出設備,交付給用戶。

2.2.2.2 從處理器的角度來看

  一開始,處理器處理從內存中拿到的監控程序的指令,並執行,這些指令讀入下一個作業的並存儲到內存中的其他部分,讀入作業後,處理器會遇到監控程序的一個分支指令,也就是跳轉指令,分支指令指導處理器在用戶程序的開始處繼續執行。於是處理器就開始執行用戶程序的指令了。直到遇到結束指令或者錯誤條件,這回導致處理器從監控程序所在位置取出指令執行。因此控制權交給作業,僅僅意味着處理器執行的指令都是從用戶程序中的指令,而控制權返回給監控程序,意味着處理器執行的是監控程序的指令。對於處理器來說,這沒有什麼分別。

  有了監控程序後,計算機的利用率提升了:一道作業完成後立馬就會開始下一道作業,沒有任何空閒時間,也很少出現作業沒完成就被終止的情況(基本上解決了串行處理的問題)。

2.2.2.3 硬件層面需要進行的支持

從上面可以看出來,監控程序就是一段普通的程序,完成固定的功能而已。
同時,爲了使這個系統工作的更加可靠,對計算機的硬件也提出了一些要求,硬件要提供一下相關的功能:

  1. 內存保護:這一點很好理解,監控程序的內存空間不能被用戶程序隨意更改——不管是有意還是無意。一旦硬件檢測到有用戶程序試圖使壞,就會將控制權直接轉移給監控程序,監控程序會取消這個作業。
  2. 定時器:這項功能是爲了防止一個作業獨佔系統,作業接管控制權後定時器自動打開。如果定時器時間到了而作業未運行完,就會停止用戶程序,將控制權返回給監控程序。
  3. 特權指令:有的機器指令會被設置成特權指令(比如 I/O 指令),只能由監控程序執行。用戶程序是不能直接使用這些指令的。當然用戶程序可以請求監控程序爲自己執行這個操作。特權指令就是爲了限制用戶程序的「權力」而設置的,畢竟老闆和員工不可能有一樣的話語權。
  4. 中斷:早期的計算機模型中並沒有中斷的能力,添加這個能力使得操作系統從用戶程序或者控制權的時候更加靈活

2.2.2.4 運行模式的概念

內存保護和特權指令引申出了程序的運行模式的概念。
用戶程序以用戶模式執行,此時有些內存區域是受保護的,特權指令也是無法執行的。
監控程序以內核模式執行,此時不僅可以執行特權指令,而且可以訪問受保護的內存區域。

2.2.3 多道批處理系統

  cpu利用率低的主要原因就是 CPU 需要等待 I/O 操作,那我們讓 CPU 忙起來不就可以了。多道批處理系統就是讓 CPU 忙起來的祕訣。方法聽起來很簡單——在內存裏多放幾道用戶程序,一旦有一個作業需要等待 I/O ,就立刻切換另一個可能不需要等待 I/O 的作業。這種處理,稱爲多道程序設計(multiprogramming)或多任務處理(multitasking)。

2.2.3.1 多道批處理系統的硬件支持

像簡單批處理系統一樣,多道程序批處理系統必須依賴於某些計算機硬件功能。
其中最顯著的功能就是支持 I/O 中斷(Interrupt)和直接存儲器訪問(Direct Memory Access,DMA)。(DMA 也需要中斷的支持)
通過中斷驅動的I/O或者DMA,處理器可以爲一個作業發出I/O命令,設備控制器執行IO操作的時候,cpu執行另一個作業;IO操作完成後,處理器被中斷,控制權傳遞給操作系統的中斷處理程序,然後操作系統再把控制權個林各一個作業(不一定是原來io請求的那個作業,這個看具體的調度方案了)

2.2.3.2 多道批處理系統需要注意的新問題

  1. 作業調度:內存的空間是有限的,意味着一次性載入到內存的程序數量也是有限的,那麼怎樣從備選作業裏選擇合適的作業加載進內存就是一個問題,這就是就是作業管理。
  2. 內存管理:選擇了作業,就需要爲作業分配空間,那從空閒區的哪一部分爲作業劃空間就是內存管理需要解決的事情。

2.2.4 分時系統

  多道批處理系統可以說是現代操作系統的雛形了,它處理批作業時對處理器的利用率也比較令人滿意,但面對多個交互作業,多道批處理系統就顯得力不從心了。
  交互作業的出現很好理解,畢竟我們現在幾乎所有應用程序都是交互式的,你滑動屏幕,這篇文章就會上下滑動,點一個分享,就會出現各種選項,等等等等。
  在交互作業中,難免需要等待用戶做出操作,但又不可能讓處理器停下來等你一個人,畢竟很多人都在用同一臺計算機,因此分時系統應運而生。
  顧名思義,分時系統就是 n 個用戶作業,操作系統控制每個用戶程序以很短的時間爲單位交替執行。因爲人的反應相對機器要慢很多,所以如果控制得當,你會感覺自己是獨佔了這一臺計算機一樣。

  第一個分時操作系統是由麻省理工學院(MIT)開發的兼容分時系統CTSS,該系統運行在一臺內存爲32000個36位字的機器上,常駐程序佔用了5000字,當控制權分配給一個交互用戶的時候,該用戶的程序和數據被載入到內容剩餘的27000個字的空間中。程序通常在第5000個字的位置開始載入,這簡化了監控程序和內存管理。系統時鐘以0.2s一個的速度產生中斷,在每個時鐘中斷出,操作系統恢復控制權,被將處理器分配給另一個用戶。在固定的時間間隔內,當前用戶被搶在,兩一個用戶被載入,這項技術稱爲時間片技術,爲了便於以後恢復,他會保留老用戶的程序狀態,在新的程序載入前,老的用戶程序會被寫入到磁盤當中。當他再次被執行的時候會先從磁盤恢復這些數據和程序。

  看到這裏,算是真正明白了操作系統的奧義,原來進程線程都算是概念的抽象罷了。實際上都是依賴中斷來產生的,監控程序再修改PC,啊,感覺真是爽。
之前理解的操作系統就是一個單獨運行的應用程序,他管理這計算機資源的方方面面,cpu調度,進程管理,內存分配等等。
  看到這裏才明白,操作系統實際上就是一組普通的程序和其他程序一樣,只是實現的功能不同而已。之前總是被進程等等概念所迷惑,這次看了這本書以後才真正解惑了。不妨從cpu的角度去理解程序運行。對於cpu來說,是無差別的,我只是根據PC(程序計數器)中的地址去取指令,然後執行,並沒有什麼進程,線程等東西。
  所謂進程,線程的切換,實際上就是cpu的PC中的值被替換到內存中不同的應用程序指令存放的地址而已。對於cpu來說,只有一個線程,就是不斷的取指令然後執行。
  那麼這個時候關鍵就是如何實現在不同的時候將PC中的值替換爲不同應用程序所在的地址。一種常用的手段是使用使用定時器中斷,因爲中斷一旦發生,cpu響應中斷的時候就會執行中斷的入口程序,實際上就是操作系統程序(也稱爲內核程序),這個時候內核就可以修改PC中的值,也就完成了應用程序的切換,實際上也就完成了所謂線程進程的切換。還有就是系統調用,比如阻塞式I/O請求,程序也會轉到監控程序進行執行,這樣的話監控程序就有機會將時間片分給別的程序了。

I/O調用的過程

  對應上面的1.9,我覺得可以這樣去描述I/O的過程,當一個線程a發起了IO調用,應爲IO屬於特權指令,所以需要進行系統調用,這個時候程序進入了內核態,cpu的使用權交給了監控程序(操作系統),操作系統會發起一個IO指令,然後修改當前線程的一些狀態,記錄他在進行io等待,之後就將cpu使用權過度到其他線程了。在該線程的IO操作完成時,會有一箇中斷產生,cpu處理這個中斷,然後把該進程的狀態置爲可調度狀態。後面就可以進行cpu的統調度了。該線程就有機會獲得cpu執行的時間片了。這樣的調度方式,對應於當前的編程模式就是阻塞式IO,在IO響應之前,該線程對應的程序將不會獲得調度。

  後來支持的nio應該就是非阻塞式的了,在發生IO調用的時候,會檢查是否爲阻塞式調用,如果是非阻塞式調用,則內核不會將進程的上下文切換,當前進程在調用完成後接着運行。同時註冊一個回調函數,在中斷回調的時候執行回調函數即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章