20135327郭皓——信息安全系統設計基礎第十一週學習總結

第十一週(11.16-11.22):

 

學習計時:共6小時linux

讀書:程序員

代碼:數組

做業:數據結構

博客:併發

1、學習目標異步

1. 瞭解異常及其種類
2. 理解進程和併發的概念
3. 掌握進程建立和控制的系統調用及函數使用:fork,exec,wait,waitpid,exit,getpid,getppid,sleep,pause,setenv,unsetenv,
4.  理解數組指針、指針數組、函數指針、指針函數的區別
5. 理解信號機制:kill,alarm,signal,sigaction
6. 掌握管道和I/O重定向:pipe, dup, dup2
 
 
 
 

第八章 異常控制流

  • 現代系統經過使控制流發生突變來對這些狀況作出反應。咱們把這些突變稱爲異常控制流ide

  • 做爲程序員,理解 ECF 很重要:函數

    • 理解 ECF 將幫助你理解重要的系統概念。
    • 理解 ECF將幫助你理解應用程序是如何與操做系統交互的。
    • 理解 ECF 將幫助你編寫有趣的新應用程序。
    • 理解 ECF 將幫助你理解並開發。
    • 理解 ECF 將幫助你理解軟件異常如何工做。
 

8.1 異常

  • 異常是異常控制流的一種形式,它一部分是由硬件實現的,一部分是由操做系統實現的
  • 異常( exception)就是控制流中的突變,用來響應處理器狀態中的某些變化。
  • 當異常處理程序完成處理後,根據引發異常的事件的類型,會發生如下三種狀況中的一種: 
    1)處理程序將控制返回給當前指令 curr 即當事件發生時正在執行的指令。 
    2) 處理程序將控制返回給 酬,即若是沒有發生異常將會執行的下一條指令。 
    3) 處理程序終止被中斷的程序。
 

8.1.1 異常處理

  • 系統中可能的每種類型的異常都分配了一個惟一的非負整數的異常號。
  • 異常表的起始地址放在一個叫作異常在基址寄存器的特殊CPU 寄存器裏。
  • 異常相似於過程調用,可是有一些重要的不 
    同之處。 
    • ·過程調用時,在跳轉處處理程序以前,處理器將返回地址壓人找中。
    • 處理器也把一些額外的處理器狀態壓到棧裏,在處理程序返回時,從新開始被中斷的程序會須要這些狀態。
    • 若是控制從一個用戶程序轉移到內核,那麼全部這些項目都被壓到內核棧中,而不是壓到用戶棧中。
    • 異常處理程序運行在內核模式下,這意味着它們對全部的系統資源都有徹底的訪問權限。
 

8.1.2 異常的類別

  • 異常能夠分爲四類:中斷( interrupt)、陷阱 (trap)、故障 (fault) 和終止 (abort)。

1.中斷工具

  • 中斷是異步發生的,是來自處理器外部的1/ 設備的信號的結果。
  • 硬件中斷的異常處理程序一般稱爲中斷處理 
    程序。
  • 剩下的異常類型(陷阱、故障和終止〉是同步發生的,是執行當前指令的結果。咱們把這類指令叫作故障指令。

2.陷阱和系統調用學習

  • 陷阱是有意的異常,是執行一條指令的結果。就像中斷處理程序同樣,陷阱處理程序將控制返回到下一條指令。陷阱最重要的用途是在用戶程序和內核之間提供一個像過程同樣的接口,叫作系統調用。

3.故障

  • 故障由錯誤狀況引發,它可能可以被故障處理程序修正。當故障發生時,處理器將控制轉移給故障處理程序。若是處理程序可以修正這個錯誤狀況,它就將控制返回到引發故障的指令,從而從新執行它。不然,處理程序返回到內核中的 abort 例程, abort 例程會終止引發故障的應用程序。

4.終止

  • 終止是不可恢復的致命錯誤形成的結果,一般是一些硬件錯誤,好比 DRAM 或者SRAM被損壞時發生的奇偶錯誤。終止處理程序從不將控制返回給應用程序。
 

8.1.3 Linux/IA32系統中的異常

  1. Linux/IA32故障和終止
  • 除法錯誤
  • 通常保護故障
  • 缺頁
  • 機器檢查

2.linuxllA32 系統調用

  • Linux 提供上百種系統調用,當應用程序想要請求內核服務時可使用,包括讀文件、寫文件或是建立一個新進程。

 

8.2 進程

  • 異常是容許操做系統提供進程 (process) 的概念所須要的基本構造塊,進程是計算機科學中 
    最深入最成功的概念之一。
  • 進程提供給應用程序的關鍵抽象: 
    • 一個獨立的邏輯控制流,它提供一個假象,好像咱們的程序獨佔地使用處理器。
    • 一個私有的地址空間,它提供一個假象,好像咱們的程序獨佔地使用存儲器系統。
 

8.2.1 邏輯控制流

  • 若是想用調試器單步執行程序,咱們會看到一系列的程序計數器 (PC)值,這些值惟一地對應於包含在程序的可執行目標文件中的指令,或者是包含在運行時動態連接到程序的共享對象中的指令。這個 PC值的序列叫作這輯控制流,或者簡稱邏輯流。
  • 每一個進程執行它的流的一部分,而後被搶佔 (preempted) (暫時掛起),而後輪到其餘進程。
 

8.2.2 併發流

  • 一個邏輯流的執行在時間上與另外一個流重疊,稱爲併發流 (concurrent fiow) ,這兩個流被稱爲併發地運行.
  • 多個流併發地執行的通常現象稱爲併發 (concurrency)。一個進程和其餘進程輪流運行的 
    概念稱爲多任務 (multitang).一個進程執行它的控制流的一部分的每一時間段叫作時間片(time slice)。所以,多任務也叫作時間分片(time.slicing).
 

8.2.3 私有地址空間

  • 進程也爲每一個程序提供一種假象,好像它獨佔地使用系統地址空間。在一臺有 位地址的機器上,地祉空間是 個可能地址的集合 0, 1,…, -l. 一個進程爲每一個程序提供它本身的私有地址空間。
 

8.2.4 用戶模式和內核模式

  • 處理器一般是用某個控制寄存器中的一個模式位 (mode bω 來提供這種功能的,該寄存器描述了進程當前享有的特權。當設置了模式位時,進程就運行在內核模式中(有時叫作超級用戶模式)。一個運行在內核模式的進程能夠執行指令集中的任何指令,而且能夠訪問系統中任何存儲器位置。
  • 沒有設置模式位時,進程就運行在用戶模式中。用戶模式中的進程不容許執行特權指令(privi1eged instruction),好比中止處理器、改變模式位,或者發起一個I/O操做。也不容許用戶模式中的進程直接引用地址空間中內核區內的代碼和數據。任何這樣的嘗試都會致使致命的保護故障。反之,用戶程序必須經過系統調用接口間接地訪問內核代碼和數據。
 

8.2.5 上下文切換

  • 操做系統內核使用一種稱爲上下丈切換 (context switch) 的較高層形式的異常控制流來實現多任務。
  • 內核爲每一個進程維持一個上下文(context)。上下文就是內核從新啓動一個被搶佔的進程所需的狀態。
  • 在進程執行的某些時刻,內核能夠決定搶佔當前進程,並從新開始一個先前被搶佔的進程。這種決定就叫作調度,是由內核中稱爲調度器( scheduler)的代碼處理的。
  • 當內核選擇一個新的進程運行時,咱們就說內核調皮了這個進程。在內核調度了一個新的進程運行後,它就搶佔當前進程,並使用一種稱爲土下丈切換的機制來將控制轉移到新的進程,上下文切換 
    1)保存當前進程的上下文, 
    2) 恢復某個先前被搶佔的進程被保存的上下文, 
    3) 將控制傳遞給這個新恢復的進程。

 

8.3 系統調用錯誤處理

見書P491

 

8.4 進程控制

 

8.4.1 獲取進程ID

  • 每一個進程都有一個惟一的正數(非零)進程 ID (PID). getpid 函數返回調用進程的 PID。getppid 畫數返回它的父進程的 PID (建立調用進程的進程〉。
  • getpid getppid 函數返回一個類型爲 pid_t 的整數值,在 Linux 系統上它在 types.h中被定義爲 int。
 

8.4.2 建立和終止進程

  • 進程老是處於下面三種狀態之-:

    • 運行。進程要麼在CPU上執行,要麼在等待被執行且最終會被內核調度。
    • 中止。進程的執行被掛起(suspend),且不會被調度。當收到 SIGSTOP、SIGTSTP、SIDTTN或者 SIGTTOU 信號時,進程就中止,而且保持中止直到它收到一個 SIGCONT 
      信號,在這個時刻,進程再次開始運行。
    • 終止。進程永遠地中止了。進程會由於三種緣由終止: 
      1) 收到一個信號,該信號的默認行爲是終止進程。 
      2) 從主程序返回。 
      3) 調用 exit 函數。
  • fork函數的特色

    • 調用一次,返回兩次
    • 併發執行
    • 相同可是獨立的地址空間
    • 共享文件

8.4.3 回收子進程

  • 當一個進程因爲某種緣由終止時,內核並非當即把它從系統中清除。相反,進程被保持在一種己終止的狀態中,直到被它的父進程回收 (reap)。當父進程回收已終止的子進程時,內核 
    將子進程的退出狀態傳遞給父進程,而後拋棄已終止的進程,今後時開始,該進程就不存在了。一個終止了但還未被回收的進程稱爲僵死進程 (zombie)。
  • waitpid函數 
    1. 判斷等待集合的成員 
      等待集合的成員是由參數 pid 來肯定的: 
      • 若是 pid>0,那麼等待集合就是一個單獨的子進程,它的進程lD等於 pid
      • 若是 pid = -1 ,那麼等待集合就是由父進程全部的子進程組成的。
    2. 修改默認行爲 
      能夠經過將 optioins 設置爲常量 WNOHANG WUNTRAα 的各類組合,修改默認行爲: 
      • WNOHANG: 若是等待集合中的任何子進程都尚未終止,那麼就當即返回(返回值爲0)。默認的行爲是掛起調用進程,直到有子進程終止。在等待子進程終止的同時,若是還想作些有用的工做,這個選項會有用。
      • WUNTRACED :掛起調用進程的執行,直到等待集合中的一個進程變成已終止或者被中止。返回的 PID 爲致使返回的己終止或被中止子進程的 PID。默認的行爲是隻返回己終止的子進程。當你想要檢查已終止和被中止的子進程時,這個選項會有用。
      • WNOHANG UNTRACED: 當即返回,若是等待集合中沒有任何子進程被中止或已終止,那麼返回值爲 ,或者返回值等於那個被中止或者己終止的子進程的 PID
    3. 檢查已回收子進程的退出狀態 
      若是 status 參數是非空的,那麼 waitpid 就會在 status 參數中放上關於致使返回的子進程的狀態信息。 wait.h 頭文件定義瞭解釋 status 參數的幾個宏 
      • WIFEXITED (status) :若是子進程經過調用 exit 或者一個返回 (return) 正常終止,就返回真。
      • WEXITSTATUS (status) 返回一個正常終止的子進程的退出狀態。只有在 WIFEXITED返回爲真時,纔會定義這個狀態。
      • WIFSIGNALED (status): 若是子進程是由於一個未被捕獲的信號終止的,那麼就返回真。
      • WTERMSIG (status): 返回致使子進程終止的信號的數量。只有在 WIFSIGNALED(status) 返回爲真時,才定義這個狀態。
      • WIFSTOPPED (status) :若是引發返回的子進程當前是被中止的,那麼就返回真。
      • WSTOPSIG (status): 返回引發子進程中止的信號的數量。只有在 WIFSTOPPED(status) 返回爲真時,才定義這個狀態。
    4. 錯誤條件 
      • 若是調用進程沒有子進程,那麼waitpid返回-1,而且設置 errno爲ECHILD。若是waitpid函數被一個信號中斷,那麼它返回一1,並設置 errno爲EINTR
    5. wait函數 
      • wait函數是waitpid函數的簡單版本。
      • 調用 wait(&status) 等價於調用 waitpid(-l &status , 0)
 

8.4.4 讓進程休眠

  • sleep函數將一個進程掛起一段指定的時間。
 

8.4.5 加載並運行程序

  • exceve函數在當前進程的上下文中加載並運行一個新程序
  • execve 函數加載並運行可執行目標文件filename,且帶參數列表 argv和環境變量列表envp。

 

8.5 信號

  • 一個信號就是一條小消息,它通知進程系統中發生了一個某種類型的事件。
 

8.5.1 信號術語

  • 傳送一個信號到目的進程是由兩個不一樣步驟組成的: 
    • 發送信號。內核經過更新目的進程上下文中的某個狀態,發送(遞送)一個信號給目的進程。發送信號能夠有以下兩個緣由: 
      1)內核檢測到一個系統事件,好比被零除錯誤或者 
      子進程終止。 
      2) 一個進程調用了kill函數,顯式地要求內核發送一個信號給目的進程。一個進程能夠發送信號給它本身。
    • 接收信號。當目的進程被內核強迫以某種方式對信號的發送作出反應時,目的進程就接收了信號。進程能夠忽略這個信號,終止或者經過執行一個稱爲信 處理程的用戶層函數捕獲這個信號。
  • 一個只發出而沒有被接收的信號叫作待處理信號。
 

8.5.2 發送信號

  1. 進程組 
    • Unix 系統提供了大量向進程發送信號的機制。全部這些機制都是基於進程組這個概念的。
    • 每一個進程都只屬於一個進程組,進程組是由一個正整數進程紐 ID來標識的。getpgrp函數返回當前進程的進程組 ID:
    • 默認地,一個子進程和它的父進程同屬於一個進程組。一個進程能夠經過使用setpgid數來改變本身或者其餘進程的進程組:

  2. 用/bin/kill 程序發送信號 

    • /bin/kill 程序能夠向另外的進程發送任意的信號。好比,命令 

ix> /bin/ki11 -9 15213

  3. 從鍵盤發送信號 

    • Unix 外殼使用做業這個抽象概念來表示爲對一個命令行求值而建立的進程。在任什麼時候刻,至多隻有一個前臺做業和個或多個後臺做業。

  4. 用kill函數發送信號 

    • 進程經過調用kill函數發送信號給其餘進程(包括它們本身)。若是pid大於黴,那麼kill函數發送信號 sig 給進程 pid。若是pid小於黴,那麼kill 發送信號 sig 給進程組 abs (pid) 中的每一個進程。

  5. 用alarm函數發送信號 

    • 進程能夠經過調用alarm函數向它本身發送SIGALRM信號。

 

8.5.3 接收信號

  • 當內核從一個異常處理程序返回,準備將控制傳遞給進程 時,它會檢查進程的未被阻塞的待處理信號的集合。若是這個集合爲空(一般狀況下),那麼內核將控制傳遞到的邏輯控制流中的下一條指令。
  • 然而,若是集合是非空的,那麼內核選擇集合中的某個信號而且強制接收信號k.收到這個信號會觸發進程的某種行爲。一旦進程完成了這個行爲,那麼控制就傳遞迴的邏輯控制流中的下一條指令(]next)。每一個信號類型都有一個預約義的默認行爲,是下面中的一種 
    • 進程終止。
    • 進程終止並轉儲存儲器 (dump core)
    • 進程中止直到被 SIGCONT 信號重啓.
    • 進程忽略該信號。

  • signal 函數能夠經過下列三種方法之一來改變和信號signum相關聯的行爲 
    • 若是 handler是SIG_IGN,那麼忽略類型爲signum的信號。
    • 若是 handler是SIG_DFL,那麼類型爲signum的信號行爲恢復爲默認行爲。
    • 不然, handler就是用戶定義的函數的地址,這個函數稱爲信號處理程序,只要進程接收到一個類型爲 signum的信號,就會調用這個程序。經過把處理程序的地址傳遞到signal函數從而改變默認行爲,這叫作設置信號處理程序。調用信號處理程序稱爲捕獲信號。執行信號處理程序稱爲處理信號。
 

8.5.4 信號處理問題

  • 對於只捕獲一個信號並終止的程序來講,信號處理是簡單直接的。然而,當一個程序要捕獲多個信號時,一些席位問題就出現了: 
    • 待處理信號被阻塞
    • 待處理信號不會排隊等待
    • 系統調用能夠被中斷
  • 重要教訓:不能夠用信號來對其它進程中發生的事件計數。
 

8.5.5 可移植的信號處理

  • 不一樣系統之間,信號處理語義的差別〈好比一個被中斷的慢速系統調用是重啓仍是永久放棄)Unix信號理的一個缺陷。爲了處理這個問題, Posix標準定義了 sigaction 函數,它容許像Linux和Solaris這樣與Posix 兼容的系統上的用戶,明確地指定他們想要的信號處理語義。
  • Signal 包裝函數設置了一個信號處理程序,其信號處理語義以下: 
    • 只有這個處理程序當前正在處理的那種類型的信號被阻塞。
    • 和全部信號實現同樣,信號不會排隊等待。
    • 只要可能,被中斷的系統調用會自動重啓。
    • 一旦設置了信號處理程序,它就會一直保持,直到 Signal帶着handler參數爲SIG_IGN或者SIG_DFL被調用。
 

8.5.6 顯式地阻塞和取消阻塞信號

  • 應用程序可使用sigprocmask函數顯式地阻塞和取消阻塞選擇的信號:
  • sigprocmask 函數改變當前已阻塞信號的集合。具 
    體的行爲依賴於 how 的值: 
    • SIG_BLOCK: 添加 set 中的信號到 blocked (blocked = blocked | set).
    • SIG_UNBLOCK: blocked 中刪除 set 中的信號 (blocked = blocked & ~set)
    • SIG_SETMASK: blocked = set
 

8.5.7 同步流以免討厭的併發錯誤

 

8.6 非本地跳轉

  • C語言提供了一種用戶級異常控制流形式,稱爲非本地跳轉,它將控制直接從一個函數轉移到另外一個當前正在執行的函數,而不須要通過正常的調用-返回序列。非本地跳轉是經過setjmp和longjmp函數來提供的。
 

8.7 操做進程的工具

  • Linux 系統提供了大量的監控和操做進程的有用工具:
    • STRACE:打印一個正在運行的程序和它的子進程調用的每一個系統調用的軌跡。
    • PS: 列出當前系統中的進程(包括僵死進程)。
    • TOP: 打印出關於當前進程資源使用的信息。
    • PMAP: 顯示進程的存儲器映射。
    • /proc: 一個虛擬文件系統,以ASCII文本格式輸出大量內核數據結構的內容,用戶程序可讀取這些內容。
 

小結

  • 異常控制流(ECF)發生在計算機系統的各個層次,是計算機系統中提供併發的基本機制。 
    • 在硬件層,異常是由處理器中的事件觸發的控制流中的突變。控制流傳遞給一個軟件處理程序,該處理程序進行一些處理,而後返回控制給被中斷的控制流。
    • 有四種不一樣類型的異常中斷、故障、終止和陸阱。當一個外部I/O設備,例如定時器芯片或者一個磁盤控制器,設置了處理器芯片上的中斷引腳時,中斷會異步地發生。
    • 控制返回到故障指令後面的那條指令。一條指令的執行可能致使故障和終止同時發生。故障處理程序會從新啓動故障指令,而終止處理程序從不將控制返回給被中斷的流。最後,陸阱就像是用來實現嚮應用提供到操做系統代碼的受控的人口點的系統調用的函數調用。 
    • 主要來講這一章要重點理解掌握代碼,理解知識點。
相關文章
相關標籤/搜索