最近在看 清大開放課程作業系統 還債XD 上次看的這次就忘了,所以想來記筆記,幫助未來自己不用再重看影片。
這次看的是關於 interrupt 的部分,探討作業系統如何做到 event-driven,避免 CPU 一直在空轉或 idle。
重點
- interrupt 的流程(軟硬體)
- 什麼是 interrupt vector & interrupt routine
- 為什麼要記住被打斷的 instruction 的 address
內容
- Busy/Wait output
- interrupt I/O
Busy/Wait output
一開始想讓電腦讀資料並處理他,最直覺就是會用這種方式,讓 CPU 一直去看 I/O 好了沒,還沒好就繼續問,問到他好了為止。但這樣做的缺點也很明顯,CPU 要忙著問進度沒辦法去做其他事情,程式在運作時仍會霸佔著 CPU,沒有辦法 multiprogramming。
程式碼大概長得像這樣:
// 讀檔
var file = file.open('file1.txt');
while(EOF) {
read_char(file);
while (peek_read_status());
current_char++;
}
但因為太浪費 CPU 資源了,所以又有了下面這個新的方法。
Interrupt I/O
這個方法就是 CPU 把自己變成更高層的老闆,然後要各部長去叫他的部員處理事情,處理完了部長再跟他說。等待的期間老闆就可以自己去找其他事做。
特點有三:
- 現在的電腦都是這個架構
- a.k.a event-driven
- interrupt 可以改變 CPU 執行的 flow
基本流程:
- CPU 跟 Controller 說:「你來幫我讀資料,讓我可以做事情 A,做完跟我說」(話音剛落,CPU 就去做其他的事情 B)
- Controller 搬完資料後,就來跟 CPU 說:「事情 A 所需的資料好了,我都放在 XXX memory」
- CPU 收到後就可以決定要繼續做 B,還是回去做 A,就看 CPU 的 scheduling
這個流程也會根據細節微調,像「interrupt 是由軟體還是硬體產生的」就可能有不同的流程。
- hardware 產生的 interrupt 就叫做
signal
- software 的叫做
trap
,有兩種狀況會產生- 不預期的:像是 segmentation fault 之類的,caused by error
- system call:所有的 system call 都是間接的,會丟出一個 interrupt 等 OS 去接,OS 想接的時候才會安排相關的 handler 去處理,完成才通知你
Signal: hardware interrupt 的流程
- hardware 會偵測到事情發生,對 OS 打一個 signal,並將正在執行的程式資訊記下來
- OS 去查 function vector 找誰是主事者,然後 call 他(稱作 service routine)
- 執行完就 return,然後回去執行原本在跑的程式
P.S: function vector 的數量是跟著硬體燒死的,所以是數量固定的 array(就是 vector)
Trap: software interrupt 的流程
It’s a trap!
- user call 一個 system call (或是跑了個除以零的程式產生 exception)
- trap 到 OS 去
- 查 switch case 表中要執行哪個程式
- 查到了就跑他
- 跑完就 return 到剛剛 call system call 的人身上
因為是軟體,system call 的數量是無上限的,想訂幾個就幾個,所以步驟三會用 switch case 的方式去寫。
共同
- 兩者都要有 interrupt vector & interrupt routine (handler)
用來對應 interrupt 和相關的 function- interrupt vector 就是個表
- interrupt rountine 就是那個被對應到的 function
- 必須要記住 被打斷的 instruction 的 address
return 時才能 resume - 之後產生的 interrupt 要能夠被 mask 掉,避免一直被打斷
所以就會有不同 priority 的 interrupt,處理高時就會忽略低