程序有下面5種正常終止方式:
(1)在main函式內執行return語句。這等效於呼叫exit。
(2)呼叫exit函式。此函式有iso c定義,其操作包括呼叫各終止處理程式(終止處理程式在呼叫atexit函式時登記),然後關閉所有標準i/o流等。
(3)呼叫_exit或_exit函式。iso c定義_exit,其目的是為程序提供一種無需執行終止處理程式或訊號處理程式而終止的方法。對標準i/o流是否進行沖洗,這取決於實現。在unix系統中,_exit和_exit是同義的,並不清洗標準i/o流。_exit函式由exit呼叫,它處理unix特定的細節。
在大多數unix系統實現中,exit(3)是標準c庫中的乙個函式,而_exit(2)則是乙個系統呼叫。
(4)程序的最後乙個執行緒在其啟動例程中執行返回語句。但是,該執行緒的返回值不會用作程序的返回值。當最後乙個執行緒從其啟動例程返回時,該程序以終止狀態0返回。
(5)程序的最後乙個執行緒呼叫pthread_exit函式。在這種情況下,程序終止狀態總是0,這與傳送給pthread_exit的引數無關。
三種異常終止方式如下:
(1)呼叫abort。它產生sigabrt訊號,這是下一種異常終止的特例。
(2)當程序接收到某些訊號時。訊號可由程序自身(例如呼叫abort函式)、其他程序或核心產生。
(3)最後乙個執行緒對「取消」(cancellation)請求作出響應。按系統預設,「取消」以延遲方式發生:乙個執行緒要求取消另乙個執行緒,一段時間之後,目標執行緒終止。
不管程序如何終止,最後都會執行核心中的同一段**。這段**為相應程序關閉所有開啟描述符,釋放它所使用的儲存器等。
對於上述任意一種終止情形,我們都希望終止程序能夠通知其父程序它是如何終止的。對於三個終止函式(exit、_exit和_exit),實現這一點的方法是,將其退出狀態(exit status)作為引數傳遞給函式。在異常終止情況下,核心(不是程序本身)產生乙個指示其異常終止原因的終止狀態(termination status)。在任意一種情況下,該終止程序的父程序都能用wait或waitpid函式取得其終止狀態。
注意,這裡使用了「退出狀態」(它是傳向exit或_exit的引數,或main的返回值)和「終止狀態」兩個術語,以表示有所區別。在最後呼叫_exit時,核心將退出狀態轉換成終止狀態(回憶圖7-1如果子程序正常終止,父程序可以獲得子程序的退出狀態。
在說明fork函式時,顯而易見,子程序是在父程序呼叫fork後生成的。上面又說了子程序將其終止狀態返回給父程序。但是如果父程序在子程序之前終止,則將如何呢?其回答是:對於父程序已經終止的所有程序,它們的父程序都改變為init程序。我們稱這些程序由init程序領養。其操作過程大致如下:在乙個程序終止時,核心逐個檢查所有活動程序,以判斷它是否是正要終止程序的子程序,如果是,則將該程序的父程序id更改為1(init程序的id)。這種處理方法保證了每個程序都有乙個父程序。
另乙個我們關心的情況是如果子程序在父程序之前終止,那麼父程序又如何能在做相應檢查時得到子程序的終止狀態呢?對此問題的回答是:核心為每個終止子程序儲存了一定量的資訊,所以當終止程序的父程序呼叫wait或waitpid時,可以得到這些資訊。這些資訊至少包括程序id、該程序的終止狀態、以及該程序使用的cpu時間總量。核心可以釋放終止程序所使用的所有儲存區,關閉其所有開啟檔案。在unix術語中,乙個已經終止,但是其父程序尚未對其進行善後處理(使用wait獲取終止子程序的有關資訊,釋放它仍占用的資源)的程序稱為僵死程序(zombie)(更多關於殭屍程序可參考:命令將僵死程序的狀態列印為z。如果編寫乙個長期執行的程式,它呼叫fork產生了很多子程序,那麼除非父程序等待取得子程序的終止狀態,否則這些子程序終止後就會變成僵死程序。
最後乙個要考慮的問題是:乙個由init程序領養的程序終止時會發生什麼?它會不會變成乙個僵死程序?對此問題的回答是:「否」,因為init被編寫成無論何時只要有乙個子程序終止,init就會呼叫wait函式取得其終止狀態。這樣也就防止了在系統中有很多僵死程序。當提及「乙個init的子程序」時,這指的可能是init直接產生的程序,也可能是其父程序已終止,由init領養的程序。
本篇博文內容摘自《unix環境高階程式設計》(第二版),僅作個人學習記錄所用。關於本書可參考:。
程序控制之exit和waitpid wait 函式
1.exit函式 我們知道,程序有五種正常終止 1 從main函式執行return語句,如同呼叫exit一樣。2 呼叫exit。此函式有iso c定義,其操作包括呼叫各中終止處理程式,然後關閉所有標準i o流等。因為iso c並不處理檔案描述符,多程序以及作業控制,所以這一定義對unix系統是不完整...
程序控制之exec函式
1.exec函式 include int execl const char pathname,const char arg0,char 0 int execv const char pathname,const char argv int execle const char pathname,con...
程序控制之system函式
1.system函式 include int system const char cmd 如果cmd是乙個空指標,則僅僅當命令處理程式可用時,system返回非0值。因為system在其實現中呼叫了fork,exec和waitpid,因此有三種返回值 1 如果fork失敗或者waitpid返回除ei...