note

參考書: 系統程式 – 第 10 章、作業系統 - Speaker Deck

其他補充參考書: Microsoft Word - 11-20.doc (wisc.edu)

作業系統

最常見的作業系統: UNIX(衍生出Linux、macos)、windows

如果電腦沒有作業系統,整個電腦就是一個行程,像是之前做的HackCUP

作業系統的五大功能模組

行程

行程的動作通常分成兩類,這兩類通常會交錯

  1. 使用CPU
  2. 使用輸出入裝置(I/O)

使用輸出入裝置的處裡時間比較長,但基本上不會使用到CPU,所以CPU可以神不知鬼不覺的處裡其他的行程

非多工作業系統如果寫無窮迴圈就會當掉,無法退出

行程的資料共享方法

通常每一個程式都是一個行程,但也有可能一個程式會分類出多個行程。但即便如此,各個行程之間通常是獨立執行的,互相之間不能共享資料。

執行緒(Thread)

執行緒的定義

  記憶體 映射表 切換速度
行程 獨立記憶體管理單元 獨立映射表,切換時需要更換映射表
執行緒 公用記記憶體管理單元,像是函數 切換時不需要更換映射表

競爭狀況與臨界區間

// P1
R1 = C
R1 = R1 + 1
C = R1
// P2
R1 = C
R1 = R1 -1
C = R1

如果兩個執行緒 P1、 P2 同時修改某個變數 V1的值為 X1,X2,那麼在修改完畢之後V1的直也可能是X1,也可能是X2,甚至是其他值,這種不明確的情形被稱為 “競爭狀況” ,而這些修改共用變數的程式區段則被稱為 “臨界區間” 。

這個問題可以用行程同步機制解決

行程同步機制的用途

利用鎖定(互斥鎖)等方式,避免兩個行程同時進入臨界區間的可能性,以便防止競爭情況的發生,但如果程式寫的不好,有可能會發生死結的問題。

行程同步機制的方法

  1. 禁止中斷
  2. 支援同步的硬體
  3. 利用 “號誌” 等 “鎖定機制”

多工

多工系統利用中斷機制避免當機,在作業系統將CPU交給一個行程之前,先設定中段時間點,以便當行程霸佔CPU時,作業系統能透過中斷機制取回CPU控制權,如此就能避免行程佔據CPU不放的行為。

中斷點通常0.1秒就會一次,所以一秒就可以輪10個行程。

排程

排程問題: 當 “執行” 狀態的行程因為輸出入而暫停時,假如系統當中有許多 “就緒” 的行程等待被執行。那麼,到底哪一個行程應該被挑選出來執行呢 ? 這個問題是作業系統的效能關鍵,所以有很多排程的方法以解決此問題。

排程的方法

循環分時排程 RR (Round-Robin Scheduling)是實務上最常使用的方法

內文切換

記憶體管理

記憶體管理的用途

有效的管理記憶體除了能提高電腦效率之外,還可以保護電腦不受到駭客或惡意程式的入侵

C 語言的記憶體分配與回收(heap)

分配: malloc()

回收: free

記憶體分配策略

第二個方法最常用

  1. 最先符合法 (First Fit): 從串列開頭開始尋找,然後將所找到的第一個足夠大的區塊分配給該程式。
  2. 下一個符合法 (Next-Fit): 使用環狀串列的結構,每次都從上一次搜尋停止的點開始搜尋,然後將所找到的第一個足夠大的區塊分配給該程式。
  3. 最佳符合法 (Best-Fit): 從頭到尾搜尋整個串列一遍,然後將大小最接近的可用區塊分配給該程式。
  4. 最差符合法 (Worst-Fit): 將大小最大的區塊分配給該程式,以便留下較大的剩餘區塊給其他程序。

記憶體如果不足(使用malloc()無法找到可用空加),就會直接回報錯誤,或是處裡記憶體不足的狀況,下面說明記憶體不足時的處裡方法

堆積空間不足時的處裡方法

記憶體聚集法(Memory Compaction)

垃圾蒐集法(Garbage Collection Algorithm))

記憶體管理單元(MMU)

常見的MMU硬體

現代的MMU都市分段分頁搭配,形成複雜的構造

磁區結構

磁區的分配

檔案系統在分配磁碟空間時,通常以一種固定大小的磁區為單位,進行區塊分配動作

磁區的組織方式

要管理這些磁區,必須使用下面兩種資料結構

  1. 鏈結串列法 (Linked List)
    • 使用鏈結串列(Linked List)紀錄可用區塊,鏈結法乃是在可用磁區中,紀錄下一個可用磁區的代號,將可用磁區一個一個串接起來。
    • 這種結構的效率很差,較好的方法是將相鄰的磁區組成群組(Group),而非單一區塊,這有助於縮短鏈結串列的長度,並藉由一次分配數個磁區而提升效率。因此鏈結串列的組織方法通常會採用磁區群組模式,而非單一磁區的鏈結方法
  2. 位元映射法 (Bit mapped)
    • 以位元映射法紀錄可用區塊,將整個磁碟的映射位元儲存在數個磁區中。
    • 如果磁碟大小為 1G,而每個磁區大小為 1K,總共會有 1G/1K = 1M 個磁區。我們可以用 1M/8 = 0.125MB 的磁碟空間,儲存整個磁碟的位元映射地圖。由於每個磁碟大小為 1K,因此整個映射圖可以被放在 0~124 號磁區中,於是我們可以用 125 個磁區紀錄整顆硬碟的一百萬個磁區之使用狀況,效率非常高,是相當經濟且快速的實作方式。

輸出入系統

如果沒有輸出入系統,程式設計師就必須研究裝置的路線配置方式。假如裝置是採用記憶體映射機制連接到電腦上,程式設計師就必須知道記憶體映射的方式,包含每一個位元或元組在此映射機制下所代表的意義,然後才能開始撰寫程式,很容易導致錯誤和Bug的發生。

輸出入系統的主要目的

驅動系統

驅動程式介紹

作業系統呼叫驅動程式的方法

Linux

Linux的基本架構,Linux 一切皆檔案

Linux中檔案相關的系統呼叫

open()、read()、write()、lseek()、stat()、opendir()、readdir()

Linux 行程管理

行程管理

執行緒

Slab 記憶體配置器

使用時機

分配方法

範例

Linux的驅動程式

功能

範例

Linux 指令