More Related Content Similar to 作業系統數位教材(劉政雄)(1 9) Similar to 作業系統數位教材(劉政雄)(1 9) (20) More from Ying wei (Joe) Chou More from Ying wei (Joe) Chou (20) 作業系統數位教材(劉政雄)(1 9)6. 何謂作業系統
由上往下看的觀點
– 可視為一個擴充機器 (extended machine)
由下往上看的觀點
– 作為資源管理者 (resource manager) 的角色
作業系統是一種資源管理者 (resource
allocator) 和常駐控制程式 (control program)
16. 批次系統
使用者必須先把工作 ( 即
想要執行的程式 ) 提交
(submit) 電腦系統
作業系統將其放入批次佇
列 (queue) 中,排隊等候
執行
依序從佇列中取出等候的
工作,並執行該工作所指
定的程式
20. 分時系統
系統輪流分配 CPU 給每個需要服務的工作,因
為發生轉換的頻率很高,所以使用者可以在每一
個程式執行的時候與其交談。
每個使用者在記憶體中存有自己的程式,當程式
執行的時候,通當只執行一個短暫的時間,且同
時輸入與輸出動作仍是交談式。
允許多個使用者同時使用一部電腦
可能會引發一些安全性的問題
50. 小結
周邊 I/O 裝置的資料傳遞方式,可以採用輪詢、
中斷驅動、或是 DMA 的方式來傳遞資料
電腦所能夠執行的工作,都必須先存放在主記憶
體中
確保電腦系統的正確執行,不受惡意或是未經除
錯的使用者軟體干擾,需要一些硬體的輔助才能
達到
65. 事件驅動模式之 GUI 系統
鍵盤事件 /ISR
滑鼠事件 /ISR
事件處理
常式
使用者
訊息佇列
使用者
應用程式
GUI 元件 A
GUI 元件 B
GUI 系統
GUI 管理程式
GUI 系統
訊息佇列
事件處理
常式
裝置驅動程式
視窗應用程式
76. 系統設計和實現
定義系統目標與規格
– 將些關鍵性 (critical) 伺服器行程在核心模式執行,
以直接存取所有的硬體,但與其他行程之間的連繫仍
透過訊息傳遞的機制
– 在核心中建立最少的機制 (mechanism) ,但是將策略
(policy) 的決定留給使用者空間的伺服器決定
實現系統
– 組合語言、 C 或是 C++ 語言
進行效能的調校
82. 行程控制表( PCB )
struct task_struct {
volatile long state;
unsigned long flags;
unsigned long policy;
int prio, static_prio;
unsigned int time_slice;
cpumask_t cpus_allowed;
/* 本行程依目前 CPU 規劃的狀態 */
struct thread_struct thread;
struct mm_struct *mm;
sigset_t blocked;
struct sigpending pending;
struct files_struct *files;
void *journal_info;
<< 其他省略 >>
}
行程狀態
輸出輸入
相關資訊
CPU 暫存器狀態
記憶體管理
相關資訊
CPU 排班相關資訊
83. 行程的觀點與 CPU 的觀點
行程 1 的
CPU 執行時
間
行程 1 的
CPU 執行時
間
行程 1 的 I/O
等待時間
行程 1 的
CPU 執行時
間
行程 1 的 I/O
等待時間
行程 1 的
CPU 執行時
間
行程 3 的
CPU 執行時
間
由行程的觀點:單一行程的執行
模式
由 CPU 的觀點:行程間的切換執
行
●●●
●●●
行程 2 的
CPU 執行時
間
84. 本文切換( Context Switch )
PC
SP
●
●
●
PC
SP
●
●
● PC
SP
●
●
●
CPU 暫存器組 新行程的記憶體舊行程的記憶體
(1) 儲存舊
行程狀態
(2) 回復新
行程狀態
程式碼
堆疊
(3) 新行程
開始執行
109. 訊息傳遞的實作方式
信號( Signal )機制
– 例如: kill (行程代碼,信號種類)
虛擬溝通管道
– 例如:管線( pipe )、信箱( mailbox )、訊息佇
列( message queue )和承接口( socket )等
輸入輸出裝置
– 例如:檔案系統
128. 循環式
行程 2 ●●● 行程 n行程 1
時間分量 1 時間分量 2 ●●● 時間分量 n
CPU
執行
計時器
遞減
142. 並行行程交錯執行的無法預期範例
int number ; // 在共用記憶體區塊
中
// 行程 A
main(){
<< 省略 >>
while(1){
<< 省略 >>
number++ ;
}
// 行程 B
main(){
<< 省略 >>
while(1){
<< 省略 >>
number-- ;
}
}
143. 無法預期的範例( 2nd )
Number 原先的值為 3
行程 A 並行執行
number++
行程 B 並行執行
number--
Number 的執行結果應該
是 3
Number++
– 暫存器 A = number
– 暫存器 A = 暫存器 A + 1
– number = 暫存器 A
Number--
– 暫存器 B = number
– 暫存器 B = 暫存器 B - 1
– number = 暫存器 B
144. 無法預期的範例( 3th )
步驟 執行行程 執行指令 執行結果
Step1 行程 A 暫存器 A = number 暫存器 A = 3
Step2 行程 A 暫存器 A = 暫存器 A + 1 暫存器 A = 4
Step3 行程 B 暫存器 B = number 暫存器 B = 3
Step4 行程 B 暫存器 B = 暫存器 B - 1 暫存器 B = 2
Step5 行程 B number = 暫存器 B number = 2
Step6 行程 A number = 暫存器 A number = 4
此種狀況稱為「競爭狀態」
147. 軟體實作的範例演算法
ProcessA(){
while (1) {
flag[0] = true;
turn = 1; /* 禮讓行程 B*/
while (flag[1] == true and
turn == 1)
{} ; /* 有人,先等等 */
<< Critical Section >>
flag[0] = false;
<< Remainder Section >>
}
}
ProcessB(){
while (1) {
flag[1] = true;
turn = 0; /* 禮讓行程 A*/
while (flag[0] == true and turn
== 0)
{} ; /* 有人,先等等 */
<< Critical Section >>
flag[1] = false;
<< Remainder Section >>
}
}
150. Test-and-set 的使用
boolean lock = false;
Process(){
while (1){
while (Test-and-set(lock)) ;
<< Critical Section >>
lock = false;
<< Remainder Section >>
}
}
152. Compare-and-swap 的使用
boolean lock = false;
Process(){
while (1) {
key = true;
while (key == true) {
Compare-and-swap(lock, key);
}
<< Critical Section >>
lock = false;
<< Remainder Section >>
}
}
153. 號誌
結構
– 一個整數變數 s
– 一個相對應的等待佇列
– 兩個必須一次完成不能被中斷執行的命令
Wait(s)
Signal(s)
種類
– 二元號誌
– 計數號誌
155. 號誌的實作
目標
– 保持 wait 及 signal 運算的不可分割性
單處理器的環境
– 不可搶先式排班
在核心中執行是安全的
– 可搶先式排班
禁止中斷
多處理器的環境
– 忙碌等待於硬體提供之同步指令
– 原因
避免所有的處理器都必須禁止中斷的重大負擔
159. 死結和飢餓
行程 1 行程 2
wait(y)
wait(x)wait(y)
wait(x)
(1) 通
過
(2) 通
過
(3) 卡
住
(4) 卡
住
signal(y
)
signal(x
)
signal(y
)signal(x
)
165. 監督程式的架構
Monitor monitor_name {
variable declarations;
function_1 definition;
function_2 definition;
function_3 definition;
……
initialization code;
}
function()
{
wait(mutex);
<< 函式的主體 >>
signal(mutex);
}
166. 情況變數
定義的情況變數 x
– Condition x;
結構
condition x {
semaphore x_sem;
int x_count;
}
合法的運算
– x.wait();
– x.signal();
170. Java 的範例
Java 監督程式
– 同步函式
public class MyShareClass {
………………….
public synchronized void mySyncMethod() {
// 省略
}
}
– Wait() 和 notify() 方法
java.util.concurrent 包裹
– 號誌
– 同步佇列
– 各類的鎖
– 不可分割運算
171. Win32 API 的範例
可使用的同步物件
– 事件( Event )
– 互斥( Mutex )
– 號誌( Semaphore )
產生物件的方法
– CreateXXX()
消滅物件的方法
– CloseHandle()
等待函式
– 等待單一物件
WaitForSingleObject()
– 等待多個物件
WaitForMultipleObjects()
喚醒等待某物件的行程或
執行緒的函式
– SendEvent()
– ReleaseMutex()
– ReleaseSemaphore()
175. 何謂死結?
行程 1 行程 2
wait(y)
wait(x)wait(y)
wait(x)
(1) 通過 (2) 通過
(4) 卡住 (3) 卡住
198. 銀行仍舊剩下 3 萬的資金來做週轉
顧客 最大會借金
額
目前借貸金額
王小明
陳小華
胡小頭
劉小文
林小強
7 萬
5 萬
8 萬
9 萬
2 萬
3 萬
1 萬
1 萬
1 萬
1 萬
211. 動態載入 (Dynamic Loading) (1)
是指使用者程式要用到的某些常式 (routine) 一
開始並不會載入記憶體中,只有當使用者程式呼
叫的時候才會載入。
程式先以可重定位的程式碼型態存在磁碟中。
212. 動態載入 (Dynamic Loading) (2)
當使用者程式載入記憶體並執行到動態載入程式
時,呼叫可重定位的鏈結載入程式 (relocatable
linking loader) 來把要用的程式載入記憶體 並執
行。
好處 :
– 不會使用到的程式碼永遠不會被載入記憶體。
213. 動態鏈結 (Dynamic Linking)
和靜態鏈結 (static linking) 區隔。
做法 :
1. 當使用者程式要用到系統程式庫時,在程式碼參考
(reference) 系統程式庫的地方做個記號 (stub) 。
2. 這段記號用來指示如何去找尋要用的程式庫 ,如果已載入記
憶體的話該去哪個位址參考,如果還沒載入的話該去磁碟的哪
裡載入。
優點 :
– 有用到的系統程式庫在記憶體裡只會存在一份,不會重複。
– 鏈結的工作只需進行一次。
– 使用動態鏈結將可使程式庫更新變得更簡單。
215. 採用重疊技巧的實例 - 兩階段組合
程式 (two-pass assembler)
兩階段組合程式 :
– 採用兩階段步驟把程式的組合碼 (assembly code) 轉
為機器碼 (machine code) 的組合程式。
要放入記憶體的資料 :
– 除了本身和其他需要的一般常式之外,還會產生第 1
次處理的程式碼、第 2 次處理的程式碼、符號表
(symbol table) 等。
226. 配置記憶體的策略
最先合適 (First-Fit) :
– 遇到第一個夠大的「坑洞」就把行程載入。
最佳合適 (Best-Fit) :
– 把每一個夠大的「坑洞」都拿來看看,然後選其中最
小的一個來載入行程。
最差合適 (Worst-Fit) :
– 也是把每個夠大的「坑洞」都拿來看看,然後選最大
的可用空間來載入行程。
229. 外部斷裂 (External Fragmentation)
有外部斷裂發生時,會「浪費」記憶體。
浪費的記憶體多寡,與選擇配置的演算法有關。
所造成的記憶體浪費程度,主要是和記憶體空間
總量以及行程的平均大小有關。
百分之五十法則 (50-percent rule)
– 在最佳的狀況下,當配置了 n 單位的記憶體空間時,
還是會因外部斷裂而多浪費了 n/2 單位的空間。
231. 解決外部斷裂的方法
內部斷裂 (Internal Fragmentation)
– 當有夠大的「坑洞」可以使用時,配置記憶體時就乾脆把整個
可用空間都要走。
– 所謂的內部斷裂,是指配置出來的記憶體裡有一小段用不到的
空間。
– 好處是減少了記憶體「小碎塊」發生的機會,可用的記憶體空
間也比較容易連續地聚集在一起。
聚集 (compaction)
– 是把記憶體內零星的可用空間收集起來,並進一步「聚集」成
大一點的「坑洞」。
239. 分頁表的實作 (2)
以 PTBR 來處理分頁表的好處是節省內容切換
(context-switch) 的時間,但是存取資料時需要多
耗費一倍的時間。
解決方法 : 改用相關暫存器 (associative
register) 或翻譯側看暫存區 (translation look-
aside buffer, TLB) 。
TLB 是由特別的高速記憶體所組成,裡面分為
兩個區域: key 區和 value 區。
241. 效能的評估
用兩種指標來評估
1. TLB 的命中率 (hit ratio):
要存取的分頁資料可以在 TLB 中找到的機率 。
2. 有效記憶體存取時間 (effective memory access
time) :
[ 有效記憶體存取時間 ] =
[ 命中率 ] × [ 在 TLB 可以找到分頁的記憶體存取總時間 ] +
(1-[ 命中率 ]) × [ 在 TLB 找不到分頁的記憶體存取總時間 ]
246. 反轉分頁表 (Inverted Page Table)
同樣是面對分頁表太大的問題,與其每個行程都配置了
一個分頁表,不如作業系統畫出一個特別的區域,專門
儲存所有行程的分頁資料。
儲存分頁資料的地方,稱為反轉分頁表 (Inverted Page
Table) 。
每一項反轉分頁表的資料會紀錄三項資訊,分別是行程
識別碼 (Process Identifier) 、此分頁在實體記憶體上對
應的欄位數和偏移量。
實體記憶體上的每個欄位在反轉分頁表中最多只會出現
1 次。
248. 分頁共用 (Shared Pages)
使用分頁機制可以共用相同的程式碼。
做法 : 把可以共用的程式碼集中在幾個分頁上,
然後標示這些分頁。
共用分頁上的程式碼,都是屬於可重入的
(reentrant) 程式碼。
共用分頁是唯讀的,不應該被修改。
採用反轉分頁表的實作對分頁共用會有困難。
249. 分段 (Segmentation) 的概念
從使用者的觀點來看,記憶體的模樣是由許多不同大小
的分段 (segment) 所組成,這些分段之間並沒有先後順
序的關係。
由這種觀點出發,衍生出來管理記憶體的方法便稱為分
段法 (Segmentation) 。
在分段法的機制中,每個分段都有一個名稱,也紀錄了
其長度。
邏輯位址即由<分段號碼,偏移量>這樣的組合所表示。
253. 分段表 (Segment Table) 的實作
和分頁表類似,可以參考分頁表的做法。
但不適合用暫存器來儲存分段表項目,應該把分段表存
於記憶體裡。
用分段表基底暫存器 (Segment Table Base Register ,
STBR) 儲存分段表的起始位置。
用分段表長度暫存器 (Segment Table Length
Register , STLR) 記錄分段表的長度。
採用相關記憶體暫存器 (associative memory register)
來儲存近來常用到的分段表資料,減輕因多一次記憶體
參考所帶來的影響。
256. 兼採分段與分頁的實例
在 Intel Pentium 架構下的 Windows XP
行程的邏輯位址空間可分為兩個部分 :
– 第一個部分由該行程自有的分段所組成,資料存放在
LDT(Local Descriptor Table) 裡。
– 第二個部分由所有行程共用的分段所組成,資料則存放在
GDT(Global Descriptor Table) 中。
行程的邏輯位址是一組 ( 選擇子,偏移量 ) 的組合。
在邏輯位址轉換為實體位址的過程中,會先產生對應的
線性位址 (linear address) 。之後遵循分頁的機制,再由
線性地址產生實體位址。
257. 邏輯位址的意義
選擇子為 16 位元的值,內容主要分為三個部分
分別用 s 、 g 、 p 來表示。
– s 分段號碼,佔 13 個位元
– g 表示此分段是位於 GDT 還是 LDT ,佔 1 個
位元
– p 代表此位址是否受到保護,佔 2 個位元
偏移量則是個 32 位元的數字,用來指示要存取
的資料是位於分段中的哪個位置。 。
267. 需求分頁 (demand paging)
基本的精神:有使用的需求,才把分頁載入。
將程式 ( 行程 ) 劃分成許多大小相同的分頁,然後當執
行中需要用到的時候,才把要用的分頁一個一個載入記
憶體。
採用有效 - 無效位元 (valid-invalid bit) 來紀錄哪些分頁已
載入記憶體中,而哪些分頁現在還在磁碟裡。
純粹需求分頁 (pure demand paging): 一開始只載入行
程進入點所在的分頁,之後再根據程式執行的需要,逐
一載入分頁。
270. 效能分析
指標
– 有效存取時間 :
存取一次記憶體所耗費的平均時間。
– 記憶體存取時間 :
真正存取一次記憶體所耗費的時間。
沒有遇到分頁錯誤時
– 需求分頁的有效存取時間會等於記憶體存取時間。
有分頁錯誤發生時
– 有效存取時間會大於記憶體存取時間 。
274. 欄位的配置 (allocation of frames)
目的
– 當有很多行程存在於記憶體時,決定該為每個行程配
置多少欄位使用。
方法
– 欄位配置演算法 (frame-allocation algorithm)
276. 欄位配置演算法
平等分配 (equal allocation)
– 讓每個行程分到一樣多的欄位。
– 假設總共有 m 個欄位可用,要分配給 n 個行程,則每個行程就
可以分到 m/n 個欄位。
比例分配 (proportional allocation)
– 根據每個行程所需的記憶體大小,依比例分配。
– 假設行程 pi
需要 si
單位的記憶體,而所有行程所需的記憶體總
量為 S 單位。
– 可用的欄位總數為 m ,分配給其中一個行程 pi
的欄位數為 ai
,
則 ai
的值 為 :
ai
= m × (si
/ S)
277. 分頁替換 (page replacement)
在行程執行的過程中,分頁會逐漸的佔據記憶體
空間。
但如果是很多個行程一起跑的話,可能會發生所
謂的過度配置 (over-allocating) ,便增加記憶體
用完的機會。
當記憶體被用完的時候,把佔用記憶體的分頁選
一些置換出來,騰出空間給別的行程用。
280. 引進修改位元的分頁替換
如果沒有可用欄位的時候,會需要進行兩次分頁轉換
( 移出分頁 1 次、寫入分頁 1 次 ) 。使分頁錯誤處理時間
增加一倍,也隨之增加有效存取時間。
這樣的代價可用引進修改位元 (modify bit) 來減輕。
首先為每個分頁與欄位多準備一個位元,一開始都設為
0 。
如果某個欄位上的分頁資料有被寫入或修改的話,那麼
此欄位的修改位元會以硬體的方式設定為 1 ,代表此欄
位上的分頁有被修改過。
當要選個「犧牲者」來取代的話,選擇修改位元為 0 的
欄位。
282. 全域替換與區域替換 (2nd)
全域替換
– 需要選一個欄位替換出去的行程,可以指定其他行程
的某個欄位替換出去。
區域替換
– 需要替換出一個欄位的行程,只能從其擁有的欄位中
選擇一個出來。
該選哪個分頁取代掉?
– 用分頁替換演算法來解決
289. LRU 演算法
LRU 演算法 (LRU algorithm) ,是當需要選出一
個分頁當「犧牲者」的時候,就選最近最少被使
用過的分頁出來替換。
採用 LRU 演算法的分頁替換會比採用 FIFO 演
算法遇到較少的分頁錯誤。
293. 各種類似 LRU 演算法的做法
由於硬體配備上的限制,有些系統沒辦法實作出
全部的 LRU 演算法。
雖然大部分的系統無法提供 LRU 演算法所需要
的硬體支援,但是至少都可以提供所謂的參考位
元 (reference bit) 讓分頁系統使用。
利用參考位元,雖然無法得知分頁被參考的順序
,但就可以設計出一些接近 LRU 演算法的做法。
294. 擴充參考位元演算法 (Additional-
Reference-Bits Algorithm) (1)
把參考位元擴充成一個 8 位元的位元組 (byte) ,位元組
的初始值為 00000000 。
在固定的週期下,根據原來的參考位元更新位元組的值
。
假設週期為 100ms ,那麼每經過 100ms 的時間之後,
作業系統會把每個分頁對應的位元組向右平移一個位元
,捨棄最低的位元,將目前每分頁的參考位元值當作位
元組最高的位元。
如此重複進行 8 次,那麼一個位元組的值剛好可以代表
8 個週期內的分頁參考歷程。
298. 加強第二次機會演算法的有序配對
1. (0, 0):
– 這樣代表分頁從來沒被參考過,也沒被修改過,適合直接替換
出去。
2. (0, 1):
– 適合選來替換出去,不過替換出去之前要先把分頁內容寫回磁
碟去,
3. (1, 0):
– 代表分頁有被參考過,不過沒有被修改過。這樣的分頁也許很
快會再被參考,所以不適合選來替換掉。
4. (1, 1):
– 表示分頁既被參考過,內容也被修改過了。最不適合選來當犧
牲者。
299. 計數器演算法 (Counter Algorithm)
專門記下每個分頁被參考的次數,來當作決定
分頁替換的依據。
為每個分頁準備個計數器,專門紀錄分頁的參
考次數。
衍生出以下兩種做法:
1. 「最不經常使用」演算法 (LFU Algorithm) 。
2. 「最常使用」演算法 (MFU Algorithm) 。
300. 分頁庫存演算法 (Page Buffering
Algorithm)
把分頁寫回磁碟和讓行程重新啟動這兩個步驟如果能夠
同時進行,說不定可以縮短許多處理的時間。
保留一個可用的欄位當「庫存 (buffer) 」。
庫存欄位的功能在於犧牲者分頁寫回磁碟的同時,可以
把要載入的分頁寫入庫存欄位中。
載入完成之後,即可重新啟動行程。
犧牲者分頁寫回磁碟的工作完成之後,裝載犧牲者分頁
的欄位即清空,成為新的庫存欄位。
301. 布雷第異常現象 (Belady’s anomaly)
在同樣的分頁參考順序下,分頁錯誤的次數在理
論上會隨著可用欄位的總數增加而減少。
但是這樣的趨勢並非在每種狀況下都成立,有時
候可用欄位的總數增加了,分頁錯誤的次數卻沒
有減少。
這種違反一般趨勢的現象,即稱為布雷第異常現
象。
307. 局部區域模型 (locality model)
認為當行程執行時,實際執行的順序可以視為在幾個不
同的局部區域 (locality) 間不斷地移動。
局部區域,是指由某段時間內同時被使用之分頁所形成
的集合。
因此,程式其實是由許多不同的局部區域所組成,而其
中可能有幾個局部區域是重疊的。
透過局部區域模型,可以做出以下的假設 :
– 若根據某個行程正在使用的局部區域而分配了足夠的欄位給此
行程,那麼除了要載入局部區域所定義的分頁之外,不會有預
期外的分頁錯誤產生。
308. 工作集合模型 (working-set model)
是局部區域模型的一種延伸。
藉著定義工作集合框架 (working-set window) 的大小來
進行。
令每兩次進行分頁參考之間的間隔時間為 1 個單位時間。
然後假設框架的大小為 Δ ,表示要進行最近 Δ 個分頁參
考的觀察。
此 Δ 個分頁所形成的集合,即定義為工作集合 (working-
set) 。
工作集合可視為一個類似於程式內的局部區域。
312. 分頁錯誤頻率 (page-fault
frequency) 策略
輾轉現象會伴隨著高頻率的分頁錯誤。
若能控制行程的分頁錯誤頻率,使其保持在某個程度之
下不再升高,則可避免輾轉現象的發生。
為分頁錯誤頻率定出上限與下限。
若偵測到分頁錯誤頻率大於上限,則要增加分配給行程
的欄位數。
若分頁錯誤頻率小於下限,則逐次減少所分配的欄位數。
控制分頁錯誤頻率於上限與下限之間,就可以達到避免
輾轉現象的效果。
314. 其他影響效能的因素
預先分頁 (Prepaging) 的方法
分頁的大小 (Page Size)
程式的結構 (Program Structure)
I/O 互相上鎖 (I/O Interlock) 的狀況
即時處理 (Real-time handling) 的需求
315. 預先分頁 (Prepaging) 的方法
在純粹需求分頁下,當剛開始執行行程時,一定會產生
一連串的分頁錯誤。這是因為系統要把起始局部區域
(initial locality) 載入記憶體的緣故。
這樣子連續產生的分頁錯誤會大幅地影響系統的效能。
為了避免這樣的狀況,可以採用預先分頁 (prepaging)
的方法。
預先分頁,是把所有需要的分頁在同一個時刻一起載入
記憶體中。
316. 分頁的大小 (Page Size)
分頁越小的話,可以越精確地把真正需要使用的資料載
入記憶體。可以避免讓不必要的資料佔據記憶體空間。
對需求分頁而言,較適合以較小的分頁來進行。
但是越小的分頁會造成越多次的分頁錯誤,增加更多次
磁碟 I/O 的工作。
由於分頁錯誤的代價還是遠大於內部斷裂所付出的代價
,故虛擬記憶體的分頁,還是傾向於使用較大的分頁。
317. 程式的結構 (Program Structure)
int A[64][64];
for(j=0; j<64; j++){
for(i=0; i<64; i++){
A[i][j] = 0;
}
}
int A[64][64];
for(i=0; i<64; i++){
for(j=0; j<64; j++){
A[i][j] = 0;
}
}
318. I/O 互相上鎖 (I/O Interlock) 的狀況
(1)
採用需求分頁時,會有某些狀況需要把一些分頁
「鎖」在實體記憶體裡。
最常見的例子是當進行大量的資料 I/O 時 ( 如與
磁帶機傳輸資料時 ) ,會需要 I/O 緩衝區。而充
當 I/O 緩衝區的分頁,便需要「鎖」在實體記憶
體內。
319. I/O 互相上鎖 (I/O Interlock) 的狀況
(2)
把 I/O 緩衝區分頁上鎖的方法 :
– 為每個欄位準備上鎖位元 (lock bit) 。
– 要進行 I/O 時,把 I/O 緩衝區分頁所在欄位之上鎖位
元設定為 1 ,這樣該欄位便不會被替換。
– I/O 完成之後,上鎖位元重設為 0 ,如此 I/O 緩衝區
分頁便回復一般分頁的身分。
使用上鎖位元具有相當的危險性。
– 若遇到某些錯誤情況,使得某個欄位被上鎖之後無法
解開,那麼此欄位就永遠沒有辦法使用。
320. 即時處理 (Real-time handling) 的需
求
使用虛擬記憶體節省了記憶體空間,卻可能造成執行時
間的延長。
如果執行的行程具備了即時處理 (real-time handling) 的
特性,那麼使用虛擬記憶體可能會使其執行失敗。
即時行程被賦予較高的優先權,以便快速取得 CPU 使
用權,然後要在最短的時間內完成執行。
使用虛擬記憶體時,會不可預期地拖長執行完成的時間
。
因此,幾乎所有的即時系統都不使用虛擬記憶體。
321. 需求分段 (demand segmentation)
缺乏硬體支援分頁法的系統,通常會採用分段法來管理
記憶體,因此也會用分段法實作虛擬記憶體。
需求分段 (demand segmentation)
– 「有需要之分段才載入記憶體」
在實際的例子上, Intel 的 80286 CPU 沒有提供分頁法
所需的硬體機制,但是有提供可以支援分段法的硬體機
制。
因此在此平台執行的 OS/2 作業系統便採用需求分段實
作虛擬記憶體。
322. OS/2 在 80286 平台的需求分段 (1)
對分段的管理,則是用分段描述子 (segment descriptor)
來紀錄與追蹤。
對虛擬記憶體的處理方法,是在分段描述子中加入一個
有效位元 (valid bit) ,用來表示此分段是否為「有效」。
當行程參考到另外一個程式分段或資料分段的位址時,
硬體會檢查該分段的有效位元。
若有效位元的值代表有效的,則行程會繼續執行。
若有效位元的值代表不是有效的,便會產生分段錯誤
(segment fault) 的中斷,載入需要的分段,之後讓行程
繼續執行。
323. OS/2 在 80286 平台的需求分段 (2)
遇到分段錯誤時,若實體記憶體的空間不夠了,
得選個分段替換出去。
OS/2 在分段描述子當中加入了存取位元
(access bit) 。只要分段中有地方被讀寫過,存
取位元就會被設為 1 。
系統準備一個佇列來保存每個分段的存取位元。
324. OS/2 在 80286 平台的需求分段 (3)
每隔一段固定時間,系統會把所有存取位元為 1
的分段紀錄挪到最前面,接著重設所有分段描述
子上的存取位元。
如此,最近有被存取過的分段總是會排在佇列中
較前面的位置。
要選擇替換的分段,從佇列的最後面開始選。
325. OS/2 在 80286 平台的需求分段 (4)
由於沒有特殊的硬體配備可以存放所有的分段資
訊,許多資訊得存在記憶體中,因此便造成了記
憶體空間上與執行時間上的浪費。
使用分段法來實作虛擬記憶體,效能並不佳。