第7章 連接程序員
連接:就是將不一樣部分的代碼和數據收集和組合成一個單一文件的的過程,這個文件可被加載(或被拷貝)到存儲器並執行。編程
連接能夠執行在編譯(源代碼被轉化爲機器代碼時)時,也能夠執行於加載(程序被加載器加載到存儲器並執行時)時,甚至執行與運行時。函數
連接是由連接器來安靜地處理的,理解連接器的好處:編碼
一、幫助你構造大型程序spa
二、避免一些危險的編程錯誤進程
三、幫助你理解語言的做用域規則是如何實現的。事件
四、理解其餘的系統概念資源
五、使你可以開發共享庫。作用域
大多數編譯系統提供編譯驅動程序,它爲用戶,根據需求調用語言預處理器、編譯器、彙編器和連接器。開發
爲了建立可執行文件,連接器必須完成兩個主要任務:
一、符號解析 (將每一個符號引用和一個符號定義聯繫起來)
二、重定位。編譯器和彙編器生成從地址零開始的代碼和數據節。連接器經過把每一個符號定義與一個存儲器位置聯繫起來,而後對其修改全部對這些符號的引用,使他們指向這個這個存儲器位置,從而重定位這些節。
目標文件:一、可重定位目標文件二、可執行目標文件三、共享目標文件
編譯器和彙編器生成可重定位目標文件(包括共享目標文件)。連接器生成可執行目標文件。
一個目標模塊就是一個字節序列,而一個目標文件就是一個存放在磁盤文件中的目標模塊。
連接器解析符號引用的方法是將每一個引用與它輸入的可重定位目標文件的符號表中的一個肯定的符號定義聯繫起來。
在編譯時,編譯器輸出每一個全局符號給彙編器,或強或弱,而彙編器把這個信息隱含地編碼在可重定位目標文件的符號表裏。函數和已初始化的全局變量是強符號,未初始化的全局變量時弱符號。
Unix連接器處理多出定義的符號的規則:
一、不容許有多個強符號
二、若是有一個強符號和許多弱符號,那麼選擇強符號
三、若是所有是若符號那麼任意選擇。
磁盤取數據要用一段相對較長的時間,因此內核執行從進程A到進程B的上下文切換,而不是在這個時間內等待什麼都不作。
每一個進程都有一個惟一的正數(非零)進程ID
對於程序員來說,咱們能夠認爲進程老是處於下面三種狀態之一:一、運行 二、暫停 三、終止
新建的子進程幾乎但不徹底與父進程相同。父進程與新建立的子進程之間最大的區別在於它們有不一樣的PID.
fork函數是有趣的,由於 它只被調用一次,卻會返回兩次。一次在調用進程(父進程)中,一次是在新建立的子進程中。在父進程中,fork返回子進程的PID.在子進程中fork返回零,由於子進程的PID老是非零的,返回值就提供一個明確的方法來分辨程序是在父進程換是在子進程中執行的。fork函數在新的子進程中運行系相同的程序,新的子進程是父進程的一個複製品。
回收子進程:當一個進程因爲某種緣由終止時,內核並非當即把它從系統中清除,取而代之的是進程被保持在一種終止狀態中,直到他被父進程收回(reaped),當父進程已經收回已終止的子進程時,內核將子進程的推出狀態傳遞給父進程,而後拋棄已終止的進程,今後時開始,該進程就不存在了。
僵死進程:一個終止了但還未被回收的進程稱。
若是父進程沒有回收它的僵死子進程就終止了,那麼內核就會安排init進程來回收他們。init進程的PID爲1.而且是在系統初始化時由內核建立的。即便僵死子進程沒有運行,它們仍然消耗系統的存儲器資源。
等待集合的成員是由參數PID來肯定的:
一、若是pid>0,那麼等待集合就是一個單獨的子進程,它的進程ID等於PID
二、若是PID=-1,那麼等待集合就是由父進程的全部子進程組成的。
讓進程休眠:sleep函數將一個進程掛起一段時間。
加載並運行程序:execve函數在當前進程的上下文中加載並運行一個新程序。
進程和程序的區別:
程序是代碼和數據的集合;程序能夠做爲目標模塊存在於磁盤上,或者做爲段存在於地址空間中。而進程是執行程序的一個特殊實例,程序老是運行在某個程序的上下文中。
信號:研究一個更高層軟件形式的異常,它容許進程中斷其餘進程。
一個信號就是一條消息,它通知進程一個某種類型的事件已經在系統中發生。
每種信號類型都對於某個類型的系統事件。
傳送一個信號到目的進程是由兩個不一樣步驟組成:一、發送信號二、接收信號。
一個只發出而沒有被接受的信號叫作待處理信號。一個待處理信號最多被接收一次。
Unix系統提供了大量的機制,用來發送信號給進程,全部這些機制都是基於進程組。
進程組:每一個進程都只屬於一個進程組,進程組是由一個正整數進程組ID來標識的。
一個子進程和它的父進程同屬於一個進程組。一個進程也能夠經過使用setpgid函數來改變本身活着其餘進程的進程組。
接收信號:當內核從一個異常處理程序返回,準備將控制傳遞給進程P時,它會檢查未被阻塞的待處理信號的集合,若是這個集合爲空(一般狀況),那麼內核傳遞控制給P的邏輯控制流中的下一條指令。
每個信號類型都有一個預約義的默認行爲:
一、進程終止。
二、進程終止並轉儲存儲器。
三、進程暫停直到被SIGCONT信號重啓。
四、進程忽略該信號。
信號處理問題:對於只捕捉一個信號並終止的程序來講信號處理是簡單直接的,然而,當一個程序要捕捉多個信號時,一些細微的問題就產生了:
一、待處理信號被阻塞。
二、帶處理信號不會排隊等待。任意類型至多隻有一個待處理信號。有第二個信號就會被簡單地丟棄。
三、系統調用能夠被中斷
非本地跳轉:C提供一種形式的用戶異常控制流,稱爲非本地跳轉,它將控制直接從一個函數轉移到另外一個當前正在執行的函數。,但不須要通過正常的調用-返回序列。
非本地跳轉的一個重要應用就是循序從一個深層嵌套的函數調用中當即返回,一般是由檢測到某個錯誤狀況而引發的。若是哦在一個深層嵌套的函數調用中發現一個錯誤狀況,咱們可使用非本地跳轉直接返回到一個普通的本地化的錯誤處理程序,而不是費力地解開調用棧。
非本地跳轉的另外一個重要應用是使一個信號處理程序分支到,一個特殊的代碼位置,而不是返回到被信號到達中斷了的指令的位置。
異常控制流發生在計算機系統的各個層次。
由四種不一樣類型的異常:中斷、故障、終止和陷阱。