在Linux系統的命令中,exit命令和_exit命令看似相同實則有著不同的作用,那麼exit命令和_exit命令具體有哪些區別呢?一起來了解下吧。
注:exit()就是退出,傳入的參數是程序退出時的狀態碼,0表示正常退出,其他表示非正常退出,一般都用-1或者1,標准C裡有EXIT_SUCCESS和EXIT_FAILURE兩個宏,用exit(EXIT_SUCCESS);可讀性比較好一點。
作為系統調用而言,_exit和exit是一對孿生兄弟,它們究竟相似到什麼程度,我們可以從Linux的源碼中找到答案:
#define __NR__exit __NR_exit /* 摘自文件include/asm-i386/unistd.h第334行 */
“__NR_”是在Linux的源碼中為每個系統調用加上的前綴,請注意第一個exit前有2條下劃線,第二個exit前只有1條下劃線。 這時隨便一個懂得C語言並且頭腦清醒的人都會說,_exit和exit沒有任何區別,但我們還要講一下這兩者之間的區別,這種區別主要體現在它們在函數庫中的定義。_exit在Linux函數庫中的原型是:
#i nclude《unistd.h》 void _exit(int status);
和exit比較一下,exit()函數定義在stdlib.h中,而_exit()定義在unistd.h中,從名字上看,stdlib.h似乎比 unistd.h高級一點,那麼,它們之間到底有什麼區別呢? _exit()函數的作用最為簡單:直接使進程停止運行,清除其使用的內存空間,並銷毀其在內核中的各種數據結構;exit() 函數則在這些基礎上作了一些包裝,在執行退出之前加了若干道工序,也是因為這個原因,有些人認為exit已經不能算是純粹的系統調用。 exit()函數與_exit()函數最大的區別就在於exit()函數在調用exit系統調用之前要檢查文件的打開情況,把文件緩沖區中的內容寫回文件,就是“清理I/O緩沖”。
exit()在結束調用它的進程之前,要進行如下步驟:
1.調用atexit()注冊的函數(出口函數);按ATEXIT注冊時相反的順序調用所有由它注冊的函數,這使得我們可以指定在程序終止時執行自己的清理動作。例如,保存程序狀態信息於某個文件,解開對共享數據庫上的鎖等。
2.cleanup();關閉所有打開的流,這將導致寫所有被緩沖的輸出,刪除用TMPFILE函數建立的所有臨時文件。
3.最後調用_exit()函數終止進程。
_exit做3件事(man): 1,Any open file descriptors belonging to the process are closed 2,any children of the process are inherited by process 1, init 3,the process‘s parent is sent a SIGCHLD signal
exit執行完清理工作後就調用_exit來終止進程。
此外,另外一種解釋:
簡單的說,exit函數將終止調用進程。在退出程序之前,所有文件關閉,緩沖輸出內容將刷新定義,並調用所有已刷新的“出口函數”(由atexit定義)。
_exit:該函數是由Posix定義的,不會運行exit handler和signal handler,在UNIX系統中不會flush標准I/O流。
簡單的說,_exit終止調用進程,但不關閉文件,不清除輸出緩存,也不調用出口函數。
共同:
不管進程是如何終止的,內核都會關閉進程打開的所有file descriptors,釋放進程使用的memory!
 12 共2頁