第1章 溫故而知新
1.3 站得高,望得遠:
計算機系統軟體體系結構采用一種層的結構,有人說過一句名言:
“計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決”
“Any problem in computer science can be solved by another layer of indirection.”
這句話幾乎概括了計算機系統軟體體系結構的設計要點,整個體系結構從上到下都是按照嚴格的層次結構設計的,
1.4 作業系統做什么:
作業系統的一個功能是 提供抽象的介面,另一個主要功能是 管理硬體資源,
從硬體的角度來說,不允許應用程式直接操作硬體;
從應用程式的角度來說,不希望在開發應用程式時直接讀寫硬體埠、處理硬體中斷等這些瑣碎事情,
1.4.2 設備驅動:
因為PC的硬體多如牛毛,作業系統開發者不可能為每個硬體開發一個驅動程式,
這些驅動程式的開發作業通常由硬體廠商完成,
作業系統開發者為硬體生產廠商提供了一系列介面和框架,凡是按照這個介面和框架開發的驅動程式都可以在該作業系統上使用,
(這就是為什么每當你插上一個新滑鼠,就會提示“正在安裝驅動程式”的原因,滑鼠的驅動程式是由硬體廠商開發好的)
1.5 記憶體不夠怎么辦:
程式直接使用記憶體的物理地址存在的問題:
- 地址空間不隔離
- 記憶體使用效率低
- 程式運行的地址不確定
解決這幾個問題的思路就是使用我們前文提到過的法寶:增加中間層,即使用一種間接的地址訪問方法,
1.5.2 分段:(Segmention)
最開始人們使用的是一種叫做“分段”(Segmention)的方法,基本思路是把一段與程式所需要的記憶體空間大小的虛擬空間映射到某個地址空間,
但分段的方法并沒有解決第二個“記憶體使用效率低”的問題,如果記憶體不足,被換入換出到磁盤的都是整個程式,這樣勢必會造成大量的磁盤訪問操作(程式從記憶體換出到磁盤,運行時再從磁盤換入到記憶體),
事實上,根據程式的區域性原理,當一個程式在運行時,在某個時間段內,它只是頻繁的用到了一小部分資料,也就是說,程式的很多資料其實在一個時間段內都是不會被用到的,
人們很自然的想到了更小粒度的記憶體分割和映射的方法,使得程式的區域性原理得到充分的利用,大大提高了記憶體的使用率,這種方法就是“分頁”(Paging),
1.5.3 分頁
分頁的基本方法是把地址空間人為的等分成固定大小的頁,每一頁的大小由硬體決定,或硬體支持多種大小的頁,由作業系統選擇決定頁的大小,
比如Intel Pentium 系列處理器支持 4KB 或 4MB 的頁大小,那么作業系統可以選擇每頁大小為4KB,也可以選擇每頁大小為4MB,但是在同一時刻只能選擇一種大小,所以對整個系統來說,頁就是固定大小的,
目前幾乎所有的PC上的作業系統都是用 4 KB 大小的頁,
虛擬地址空間 和 物理地址空間 都是一樣的分法,
那么,當我們把行程的虛擬地址空間按頁分割,把常用的資料和代碼頁裝載到記憶體中,把不常用的代碼和資料保存在磁盤里,當需要用到的時候再把它從磁盤里取出來即可,

頁錯誤(Page Fault):
圖1-6中 Process1 的 VP2 和 VP3 不在記憶體中,但是當行程需要用到這兩個頁的時候,硬體會捕獲到這個訊息,就是所謂的“頁錯誤”(Page Fault),然后作業系統接管行程,負責將 VP2 和 VP3 從磁盤中讀出來并裝入到記憶體,然后將記憶體中的這兩個頁與 VP2 和 VP3 之間建立映射關系,
保護也是頁映射的目的之一,簡單的說就是每個也可以設定權限屬性,誰可以修改,誰可以訪問等,而只有作業系統有權限修改這些屬性,那么作業系統就可以做到保護自己和保護行程,

虛擬存盤的實作需要依靠硬體的支持,對不不同的CPU來說是不同的,但是幾乎所有的硬體都采用一個叫 MMU(Memory Management Unit)的部件來進行頁映射,
一般 MMU 都集成在CPU內部,不會以單獨的部件存在,
1.6 眾人拾柴火焰高:
1.6.1 執行緒基礎:
在Linux下,用以下方法可以創建一個新的任務:
- fork:復制當前行程
- exec:使用新的可執行映像覆寫當前可執行映像
- clone:創建子行程并從指定位置開始執行
fork函式產生一個和當前行程完全一樣的新行程,
fork函式產生新任務的速度非常快,因為fork并不復制原任務的記憶體空間,而是和原任務一起共享一個 “寫時復制”(Copy On Write,COW) 的記憶體空間,
所謂“寫時復制”,指的是兩個任務可以同時自由的讀取記憶體,但任意一個任務試圖對記憶體進行修改時,記憶體就會復制一份提供給修改方單獨使用,以免影響到其他的任務使用,
fork只能夠產生本任務的鏡像,因此須要使用 exec 配合才能夠啟動別的新任務,
exec可以用新的可執行映像替換當前的可執行映像,因此在fork產生了一個新任務之后,新任務可以呼叫exec來執行新的可執行檔案,
fork和exec通常用于產生新任務,而如果要產生新執行緒,則可以使用clone,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/350836.html
標籤:其他
上一篇:429. N 叉樹的層序遍歷
