exit和exit的區別?

2021-06-27 12:06:49 字數 2339 閱讀 7488

_exit終止呼叫程序,但不關閉檔案,不清除輸出快取,也不呼叫出口函式。

exit函式將終止呼叫程序。在退出程式之前,所有檔案關閉,緩衝輸出內容

將重新整理定義,並呼叫所有已重新整理的「出口函式」(由atexit定義)。

作為系統呼叫而言,_exit和exit是一對孿生兄弟,它們究竟相似到什麼程度,我們可以從linux的原始碼中找到答案:

#define __nr__exit __nr_exit  

"__nr_"是在linux的原始碼中為每個系統呼叫加上的字首,請注意第乙個exit前有2條下劃線,第二個exit前只有1條下劃線。

這時隨便乙個懂得c語言並且頭腦清醒的人都會說,_exit和exit沒有任何區別,但我們還要講一下這兩者之間的區別,這種區別主要體現在它們在函式庫中的定義。_exit在linux函式庫中的原型是:

#i ncludevoid _exit(int status); 

和exit比較一下,exit()函式定義在stdlib.h中,而_exit()定義在unistd.h中,從名字上看,stdlib.h似乎比 unistd.h高階一點,那麼,它們之間到底有什麼區別呢?

_exit()函式的作用最為簡單:直接使程序停止執行,清除其使用的記憶體空間,並銷毀其在核心中的各種資料結構;exit() 函式則在這些基礎上作了一些包裝,在執行退出之前加了若干道工序,也是因為這個原因,有些人認為exit已經不能算是純粹的系統呼叫。

exit()函式與_exit()函式最大的區別就在於exit()函式在呼叫exit系統呼叫之前要檢查檔案的開啟情況,把檔案緩衝區中的內容寫回檔案,就是"清理i/o緩衝"。

在linux的標準函式庫中,有一套稱作"高階i/o"的函式,我們熟知的printf()、fopen()、fread()、fwrite()都在此列,它們也被稱作"緩衝i/o(buffered i/o)",其特徵是對應每乙個開啟的檔案,在記憶體中都有一片緩衝區,每次讀檔案時,會多讀出若干條記錄,這樣下次讀檔案時就可以直接從記憶體的緩衝區中讀取,每次寫檔案的時候,也僅僅是寫入記憶體中的緩衝區,等滿足了一定的條件(達到一定數量,或遇到特定字元,如換行符和檔案結束符eof),再將緩衝區中的內容一次性寫入檔案,這樣就大大增加了檔案讀寫的速度,但也為我們程式設計帶來了一點點麻煩。如果有一些資料,我們認為已經寫入了檔案,實際上因為沒有滿足特定的條件,它們還只是儲存在緩衝區內,這時我們用_exit()函式直接將程序關閉,緩衝區中的資料就會丟失,反之,如果想保證資料的完整性,就一定要使用exit()函式。

請看以下例程:

#i nclude

main()

編譯並執行:

$gcc exit2.c -o exit2

$./exit2

output begin

content in buffer

#i nclude

main()

編譯並執行:

$gcc _exit1.c -o _exit1

$./_exit1

output begin

在linux中,標準輸入和標準輸出都是作為檔案處理的,雖然是一類特殊的檔案,但從程式設計師的角度來看,它們和硬碟上儲存資料的普通檔案並沒有任何區別。與所有其他檔案一樣,它們在開啟後也有自己的緩衝區。

此外,另外一種解釋:

簡單的說,exit函式將終止呼叫程序。在退出程式之前,所有檔案關閉,緩衝輸出內容將重新整理定義,並呼叫所有已重新整理的「出口函式」(由atexit定義)。

_exit:該函式是由posix定義的,不會執行exit handler和signal handler,在unix系統中不會flush標準i/o流。

簡單的說,_exit終止呼叫程序,但不關閉檔案,不清除輸出快取,也不呼叫出口函式。

共同:不管程序是如何終止的,核心都會關閉程序開啟的所有file descriptors,釋放程序使用的memory!

note:

在由『fork()』建立的子程序分支裡,正常情況下使用『exit()』是不正確的,這是因為使用它會導致標準輸入輸出的緩衝區被清空兩次,而且臨時檔案被出乎意料的刪除(譯者注:臨時檔案由tmpfile函式建立在系統臨時目錄下,檔名由系統隨機生成)。

在c++程式中情況會更糟,因為靜態目標(static objects)的析構函式(destructors)可以被錯誤地執行。

還有一些特殊情況,比如守護程式,它們的父程序需要呼叫『_exit()』而不是子程序;適用於絕大多數情況的基本規則是,『exit()』在每一次進入『main』函式後只呼叫一次。

在由『vfork()』建立的子程序分支裡,『exit()』的使用將更加危險,因為它將影響父程序的狀態

注:exit()就是退出,傳入的引數是程式退出時的狀態碼,0表示正常退出,其他表示非正常退出,一般都用-1,標準c裡有exit_success和exit_failure兩個巨集,用exit(exit_success);可讀性比較好一點。

exit和exit的區別

在linux的標準庫函式中,有一套稱作高階i o的函式,我們熟知的printf fopen fread fwrite都在此列,他們也被稱作緩衝 i o。其特徵是對應每乙個開啟的檔案,都存在乙個緩衝區,在記憶體中都有一片緩衝區,每次讀檔案會多讀若干條記錄,這樣下次讀檔案時就可以直接從記憶體的快取中取出...

exit 和 exit 的區別

exit 和 exit 的效果都是讓程式退出執行,而 exit 用來 盡快 退出。先說一下atexit 函式。我們可以用atexit 註冊乙個或多個函式退出清理函式 或者on exit 但這個函式不建議用 這些清理函式按照註冊時的反順序,在exit 或main函式return時被呼叫。include...

exit和exit的區別

在linux的標準庫函式中,有一套稱作高階i o的函式,我們熟知的printf fopen fread fwrite都在此列,他們也被稱作緩衝 i o。其特徵是對應每乙個開啟的檔案,都存在乙個緩衝區,在記憶體中都有一片緩衝區,每次讀檔案會多讀若干條記錄,這樣下次讀檔案時就可以直接從記憶體的快取中取出...