第八章-------異常控制流

第八章-------異常控制流

       比如,一個硬件定時器定期產生信號,這個時間必須得到處理。包括到達網絡適配器後,必須存放在內存中。程序向磁盤請求數據,然後休眠,直到被通知說數據已就緒。當子進程終止時,創造這些子進程的父進程必須得到通知。現代系統通過控制流發生突變來對這些情況做出反應,一般而言,我們把這些突變稱爲異常控制流(Exceptional Control Flow, ECF)。
1.異常
      在任何情況下,當處理器檢測到有事件發生時,它就會通過一張叫做異常表的跳轉表,進行一個間接過程調用(異常),到一個專門設計用來處理這類事件的操作系統子程序(異常處理程序)。當異常處理程序完成處理後,根據引起異常的事件的類型,會發生以下三種情況中的一種:
      ● 處理程序將控制返回給當前指令,即當事件發生時正在執行的指令。
      ● 處理程序將控制返回給,如果沒有發生異常將會執行的下一條指令。
      ● 處理程序終止被中斷的程序。
      
       ①異常處理
       在系統啓動時(當計算機重啓或者加電時),操作系統分配和初始化一張稱爲異常表的跳轉表,使得表目k包含異常k的處理程序的地址。在運行時(當系統在執行某個程序時),處理器檢測到發生了一個事件,並且確定了相應的異常號k。隨後,處理器發生異常,方法是執行間接過程調用,通過異常表的表目k,轉到相應的處理程序。如下圖:
      
      處理器如何使用異常表來形成適當的異常處理程序的地址?
      異常號是到異常表中的索引,異常表的起始地址放在一個叫做異常表基址寄存器的特殊CPU寄存器裏。
      
     ②異常的類別
      異常可以分爲四類:中斷、陷阱、故障和終止。
      
2.進程
      進程的經典定義就是一個執行中程序的實例。系統中的每個程序都運行在某個進程的上下文中。上下文是由程序正確運行所需的狀態組成的。這個狀態包括存放在內存中的程序的代碼和數據,它的棧、通用目的寄存器的內容、程序計數器、環境變量以及打開文件描述符的集合。
      ①邏輯控制流
      即使在系統中通常有許多其他程序在運行,進程也可以向每個程序提供一種假象,好像它在獨佔的使用處理器。如果想用調試器單步執行程序,我們會看到一系列程序計數器(PC)的值,這些值唯一地對應於包含在程序的可執行目標文件中的指令,或是包含在運行時動態鏈接到程序的共享對象中的指令。這個PC值得序列叫做邏輯控制流,或者簡稱邏輯流。
              
       ②併發流
       多個流併發的執行的一般現象被稱爲併發。一個進程和其他進程輪流運行的概念稱爲多任務。一個進程執行它的控制流的一部分的每一時間叫做時間片。因此多任務也叫做時間分片。
       ③私有地址空間
       地址空間底部是保留給用戶程序的,包括通常的代碼、數據、堆和棧段。代碼段總是從地址0x400000開始。地址空間頂部保留給內核(操作系統常駐內存的部分)。地址空間的這個部分包含內核在代表進程執行指令時(比如當應用程序執行系統調用時)使用的代碼、數據和棧。
       
       ④ 用戶模式和內核模式
       運行應用程序代碼的進程初始時實在用戶模式中的。進程從用戶模式變爲內核模式的唯一方法是通過諸如中斷、故障或者陷入系統調用這樣的異常。當異常發生時,控制傳遞到異常處理程序,處理器將模式從用戶模式變爲內核模式。處理程序運行在內核模式中,當它返回到應用程序代碼時,處理器就把模式從內核模式該回到用戶模式。
       Linux提供了一種聰明的機制,叫做/proc文件系統,它允許用戶模式進程訪問內核數據結構的內容。/proc文件系統將許多內核數據結構的內容輸出爲一個用戶程序可以讀的文本文件的層次結構。比如,你可以使用/proc文件系統找出一般的系統屬性,比如:CPU類型(/proc/cpuinfo),或者某個特殊的進程使用的內存段(/proc/<process-id>/maps)。
        上下文切換
       操作系統內核使用一種稱爲上下文切換的較高層形式的異常控制流來實現多任務。
       內核爲每一個進程維持一個上下文。上下文就是內核重新啓動一個被搶佔的進程所需的狀態。它由一些對象的值組成,這些對象包括通用目的寄存器、浮點寄存器、程序計數器、用戶棧、狀態寄存器、內核棧和各種內核數據結構,比如描述地址空間的頁表、包含有關當前進程信息的進程表,以及包含進程一打開文件信息的文件表。
       在進程執行的某些時刻,內核可以決定搶佔當前進程,並重新開始一個先前被搶佔了的進程。這種決策就叫做調度,是由內核中稱爲調度器的代碼處理的。當內核選擇一個新的進程運行時,我們說內核調度了這個進程。在內核調度了一個新的進程運行後,它就搶佔當前進程,並使用一種稱爲上下文切換的機制來將控制轉移到新的進程,上下文切換1)保存當前進程的上下文,2)恢復某個先前被搶佔的進程被保存的上下文,3)將控制傳遞給這個新回覆的進程。
       當內核代表用戶執行系統調用時,可能會發生上下文切換。如果系統調用因爲等待某個事件的發生而阻塞,那麼內核可以讓當前進程休眠,切換到另一個進程。比如,如果個read系統調用需要訪問磁盤,內核可以選擇執行上下文切換,運行另外一個進程,而不是等待數據從磁盤到達。另一個示例是sleep系統調用,它顯示地請求讓調用進程休眠。    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章