第八章 異常控制流
(1)控制流:控制轉移序列。
控制轉移:從一條指令到下一條指令。
異常控制流:現代作業系統通過使控制流發生突變來對系統狀态做出反應,這些突變稱為異常控制流。
(2)異常:硬體觸發異常,軟體處理異常

(3)異常處理
異常表:當處理器檢測到有事件發生時,它會通過跳轉表,進行一個間接過程調用(異常),到異常處理程式。
異常号:系統中可能的某種類型的異常都配置設定了一個唯一的非負整數的異常号。異常号是到異常表中的索引。
一旦硬體觸發了異常,異常處理程式則由軟體完成。
(4)異常的類别——中斷、陷阱、故障和終止
a)中斷處理:異步是指硬體中斷不是由任何一條指令造成的,而是由外部I/O裝置的事件造成的。
b)陷阱和系統調用:系統調用是一些封裝好的函數,内部通過指令int n實作。陷阱最重要的用途是提供系統調用。系統調用運作在核心模式中,并且可以通路核心中的棧。系統調用的參數是通過通用寄存器而不是棧來傳遞的,如,%eax存儲系統調用号,%ebx,%ecx,%edx,%esi,%edi,%ebp最多存儲六個參數,%esp不能用,因為進入核心模式後,會覆寫掉它。
c)故障
d)終止
(5)程序(作業系統層):邏輯控制流,私有位址空間,多任務,并發,并行,上下文,上下文切換,排程。程序就是一個執行中的程式執行個體。系統中的每個程式都是運作在某個程序的上下文中的。 程序提供給應用程式的關鍵抽象:a)一個獨立的邏輯控制流 ;b)一個私有的位址空間
#邏輯控制流- 程式計數器(PC)值的序列叫做邏輯控制流,簡稱邏輯流。如下圖所示,處理器的一個實體控制流分成了三個邏輯流,每個程序一個。
一些概念:并發流:并發流一個邏輯流的執行在時間上與另一個流重疊
并發:多個流并發執行的一般現象稱為并發。
多任務:多個程序并發叫做多任務。
并行:并發流在不同的cpu或計算機上,
#私有位址空間-一個程序為每個程式提供它自己的私有位址空間。運作應用程式代碼的程序初始時是在使用者模式中的。程序從使用者模式變為核心模式的唯一方法是通過異常。linux提供了/proc檔案系統,它允許使用者模式程序通路核心資料結構的内容。
(6)程序控制
建立和終止程序:程序的三種狀态——運作、停止和終止。程序會因為三種原因終止程序:收到信号,該信号預設終止程序;從主程式傳回;調用exit函數。
(7)回收子程序:
回收:當一個程序終止時,核心并不立即把它從系統中清除。相反,程序被保持在一種已終止的狀态中,直到被它的父程序回收。
僵死程序:一個終止了但是還未被回收的程序稱為僵死程序。
回收子程序的兩種方法:1,核心的init程序 2,父程序waitpid函數
-如果父程序沒有回收它的僵死子程序就終止了,那麼核心就會安排init進城來回收它們。init程序的PID為1,并且是在系統初始化時建立的。
-個程序可以通過調用waitpid函數來等待它的子程序終止或停止。
waitpid函數有點複雜,預設地(當options=0時),waitpid挂起調用程序的執行,知道它的等待集合中的一個子程序終止。
(8) wait函數:
wait(&status)函數,等價于調用wait(-1,&status,0)
讓程序休眠:
sleep函數将一個程序挂起一段指定的時間。
pause函數讓調用函數休眠,知道該程序收到一個信号。
(9)環境數組操作函數:
(10)信号(作業系統和應用程式之間):程序之間傳送信号,一種更高層次的軟體形式的異常,稱為unix信号,它允許程序中斷其他程序。低層的硬體異常是由核心異常處理程式處理的,正常情況下,對使用者程序而言是不可見的。信号提供了一種機制,通知使用者程序發生了這些異常。
(11)信号處理過程
#發送信号:核心通過更新目的程序中上下文中的某個狀态,發送一個信号給目的程序。發送信号有兩個原因:a)核心檢測到一個系統事件; b)一個程序調用kill函數,心事發送信号
#接收信号:,目的程序就接收了信号。程序可以忽略這個信号,終止或者通過執行信号處理程式捕獲這個信号。
注意:待處理信号,一種類型的信号隻能有一種待處理信号,多餘的不會排隊,而是會舍掉 ; 信号還可以阻塞。
(12)發送信号:/bin/kill , kill函數,鍵盤,alarm函數
程序組:每個程序都隻屬于一個程序組,程序組是由一個程序組ID來辨別的。預設的,一個子程序和它的父程序同屬于一個程序組。在任何時刻,至多隻有一個前台作業和0個或多個背景作業。外殼為每個作業建立一個獨立的程序組,一個作業對應一個程序組。
用kill函數發送信号:發送SIGKILL信号
用alarm函數發送信号:發送SOGALARM信号
(13)接收信号,程序可以通過使用signal函數來修改和信号相關的預設行為。唯一的例外是SIGSTOP和SIGKILL,它們的預設行為不能被修改。
(14)信号處理問題, 當一個程式捕獲多個信号時,容易有一些細問問題:
可移植的信号處理:目的是為了統一同一信号在不通系統中的語義。sigaction函數,或者是它的包裝函數Signal函數。
(15)同步流以避免并發的錯誤,如何編寫讀寫相同存儲位置的并發流程式的問題,困擾着數代計算機科學家。比如,競争問題。程式示例如下:
容易出現以下問題:
(16)非本地跳轉(應用層) c語言提供了一種使用者級異常控制流形式,稱為本地跳轉。通過setjmp和longjmp函數來提供。
setjmp函數隻被調用一次,但傳回多次:一次是當第一次調用setjmp,而調用環境儲存在緩沖區env中時,一次是為每個相應的longjmp調用。另一方面,longjmp隻調用一次,但從不傳回。sig—函數是setjmp和longjmp函數的可以被信号處理程式使用的版本。
非本地跳轉的一個重要應用就是允許從一個深層嵌套的函數調用中立即傳回,通常是由檢測到某個錯誤情況引起的。
非本地跳轉的另一個重要應用是使一個信号處理程式分支到一個特殊的代碼位置,而不是傳回到達中斷了的指令位置。
遇到的問題
- 教材:第八章,詳細學習指導:http://group.cnblogs.com/topic/73069.html
- 課程資料:https://www.shiyanlou.com/courses/413 實驗十,課程邀請碼:W7FQKW4Y
- 教材中代碼運作、思考一下,讀代碼的學習方法:http://www.cnblogs.com/rocedu/p/4837092.html。
- http://blog.csdn.net/zhanghaodx082/article/details/12280689