控制流:控制轉移序列。linux
異常控制流:現代操做系統經過使控制流發生突變來對系統狀態作出反應,這些突變稱爲異常控制流。數組
異常的剖析,以下圖所示:bash
異常表:當處理器檢測到有事件發生時,它會經過跳轉表,進行一個間接過程調用(異常),到異常處理程序。服務器
異常號:系統中可能的某種類型的異常都分配了一個惟一的非負整數的異常號。異常號是到異常表中的索引。數據結構
一旦硬件觸發了異常,異常處理程序則由軟件完成。併發
Linux/IA32故障和終止函數
- 除法錯誤 - 通常保護故障 - 缺頁 - 機器檢查
程序計數器(PC)值的序列叫作邏輯控制流,簡稱邏輯流。以下圖所示,處理器的一個物理控制流分紅了三個邏輯流,每一個進程一個。學習
運行應用程序代碼的進程初始時是在用戶模式中的。進程從用戶模式變爲內核模式的惟一方法是經過異常。 linux提供了/proc文件系統,它容許用戶模式進程訪問內核數據結構的內容。
當內核表明用戶執行上下文切換時,可能會發生上下文切換。若是系統調用發生阻塞,那麼內核可讓當前進程休眠,切換到另外一個進程,如read系統調用,或者sleep會顯示地請求讓調用進程休眠。通常,即便系統調用沒有阻塞,內核亦能夠決定上下文切換,而不是將控制返回給調用進程。ui
中斷也可能引發上下文切換。如,定時器中斷。操作系統
waitpid函數有點複雜,默認地(當options=0時),waitpid掛起調用進程的執行,知道它的等待集合中的一個子進程終止。
1.斷定等待集合的成員 2.修改默認行爲 3.檢查已回收子進程的退出狀態 4.錯誤條件 5.wait函數 6.使用waitpid的示例
若是請求的時間量已經到了,sleep返回0,不然返回還剩下的要休眠的秒數。後一種狀況是可能的,若是由於sleep函數被一個信號中斷而過早地返回。咱們將在8.5節中詳細討論信號
pause函數讓調用函數休眠,直到該進程收到一個信號。
execve函數加載並運行可執行目標文件filename,且帶參數列表argv和環境變量列表envp。只有當出現錯誤時,例如找不到filename,execve纔會返回到調用程序。因此,與fork一次調用返回兩次不一樣,execve調用一次並從不返回。
參數中每一個指針都指向一個參數串。按照慣例,argv[0]是可執行目標文件的名字。環境變量的列表是由一個相似的數據結構表示的。envp變量指向一個以null結尾的指針數組,其中每一個指針指向個環境變量串,其中每一個串都是形如「NAME=VALUE」的名字一值對。
像Unix外殼和Web服務器這樣的程序大量使用了fork和e×ecve函數。外殼是一個交互型的應用程序,它表明用戶運行其餘程序。最先的外殼是Sh程序,後面出現了一些變種,好比csh、tcsh、ksh和bash。外殼執行一系列的讀/求值(readeaUte)步驟而後終止。
若是builtin_command返回0,那麼外殼建立一個子進程,並在子進程中執行所請求的程序。若是用戶要求在後臺運行該程序,那麼外殼返回到循環的頂部,等待下一個命令行不然,外殼使用Waitpid函數等待做業終止。看成業終止時,外殼就開始下一輪迭代。注意這個簡單的外殼是有缺陷的,由於它並不回收它的後臺子進程。修改這個缺陷就要求使用信號。
1.進程組
當內核從一個異常處理程序返回,準備將控制傳遞給進程P時,他會檢查進程P的未被阻塞的處理信號的集合。若是這個集合爲空,那麼內核將控制傳遞到P的邏輯控制流中的下一條指令;若是集合是非空的,那麼內核選擇集合中的某個信號K(一般是最小的K0,而且強制P接收信號K。收到這個信號會觸發進程的某種行爲。一旦進程完成了這個行爲,那麼控制就傳遞迴P的邏輯控制流中的下一條指令。
信號處理程序的執行中斷main C函數的執行,相似於底層異常處理程序中斷當前應用程序的控制流的方式,由於信號處理程序的邏輯控制流與主函數的邏輯控制流重疊,信號處理程序和主函數併發地運行。
(4)一旦設置了信號處理程序,它就會一直保持,知道signal帶着handler參數爲SIG_IGN或者SIG_DFL被調用。
-調用兩次fork,一共產生四個子進程,打印四個輸出行,規律爲2的n次方
getpid返回調用進程的PID
getppid返回它的父進程的PID
-此程序指定了環境變量,而後依然執行了ls -l指令,成功後沒有返回,因此最後一句話不會輸出,結果依然相同。