有8種方式使進程終止(termination),其中5種為正常終止,它們是:
(1)從main返回。
(2)調用exit。
(3)調用_exit或_Exit。
(4)最後一個線程從其啟動常式返回。
(5)最後一個線程調用pthread_exit。
異常終止有3種方式,它們是:
(6)調用abort。
(7)接到一個訊號並終止。
(8)最後一個線程對取消請求作出響應。
啟動常式是這樣編寫的,使得從main返回後立即調用exit函數。(關於啟動常式:http://learn.akae.cn/media/ch19s02.html)。如果將啟動常式以C代碼形式表示(實際上該常式常常用組合語言編寫),則它調用main函數的形式可能是:
exit( main( argc, argv ) );
1、exit函數
有三個函數用於正常終止一個程式:_exit和_Exit立即進入核心,exit則先執行一些清理處理(包括調用執行各終止處理常式,關閉所有標準I/O流等),然後進入核心。
#include <stdlib.h> exit( _Exit( <unistd.h> _exit( status );
exit函數總是執行一個標準I/O庫的清理關閉操作:為所有開啟流調用fclose函數。這會造成所有緩衝的輸出資料都被沖洗(寫到檔案上)。
三個exit函數都帶一個整型參數,稱為終止狀態(或退出狀態,exit status)。大多數UNIX shell都提供檢查進程終止狀態的方法。如果(a)若調用這些函數時不帶終止狀態,或(b)main執行了一個無傳回值的return語句,或(c)main沒有聲明傳回型別為整型,則該進程的終止狀態是未定義的。但是,若main的傳回型別是整型,並且main執行到最後一條語句時返回(隱式返回),那麼該進程的終止狀態是0。
main函數返回一整型值與用該值調用exit是等價的。於是在main函數中
exit(0); 等價於 return(0);
2、atexit函數
按照ISO C規定,一個進程可以登記多達32個函數,這些函數將由exit自動調用。我們稱這些函數為終止處理常式(exit handler),並調用atexit函數來登記這些函數。
#include <stdlib.h> atexit( (*func)(
其中,atexit的參數是一個函數地址,當調用此函數時無需向它傳遞任何參數,也不期望它返回一個值。exit調用這些函數的順序與它們登記時候的順序相反。同一函數若登記多次,則也會被調用多次。
根據ISO C和POSIX.1,exit首先調用各終止處理常式,然後按需要多次調用fclose,關閉所有開啟流。POSIX.1擴充了ISO C標準,它指定如若程式調用exec函數族中的任一函數,則將清除所有已安裝的終止處理常式。圖7-1顯示了一個C程式是如何啟動的,以及它可以終止的各種方式。
my_exit1( my_exit2((atexit(my_exit2) != (atexit(my_exit1) != (atexit(my_exit1) != (
執行該程式產生:
[root@localhost apue]# ./prog7-
終止處理常式每登記一次,就會被調用一次。在程式清單7-2中,第一個終止處理常式被登記兩次,所以也會被調用兩次。
本篇博文內容摘自《UNIX環境進階編程》(第二版),僅作個人學習記錄所用。關於本書可參考:http://www.apuebook.com/。