系統(tǒng)之家 - 系統(tǒng)光盤下載網(wǎng)站!

當(dāng)前位置:系統(tǒng)之家 > 系統(tǒng)教程 > Linux下exit命令

Linux下exit命令和_exit命令區(qū)別盤點(diǎn)(2)

時(shí)間:2014-12-09 10:04:48 作者:qipeng 來(lái)源:系統(tǒng)之家 1. 掃描二維碼隨時(shí)看資訊 2. 請(qǐng)使用手機(jī)瀏覽器訪問(wèn): https://m.xitongzhijia.net/xtjc/20141208/32064.html 手機(jī)查看 評(píng)論

  更詳細(xì)的介紹:

  Calling exit() The exit() function causes normal program termination.

  The exit() function performs the following functions:

  1. All functions registered by the Standard C atexit() function are called in the reverse order of registration. If any of these functions calls exit(), the results are not portable. 2. All open output streams are flushed (data written out) and the streams are closed.

  3. All files created by tmpfile() are deleted.

  4. The _exit() function is called. Calling _exit() The _exit() function performs operating system-specific program termination functions. These include: 1. All open file descriptors and directory streams are closed.

  2. If the parent process is executing a wait() or waitpid(), the parent wakes up and status is made available.

  3. If the parent is not executing a wait() or waitpid(), the status is saved for return to the parent on a subsequent wait() or waitpid()。 4. Children of the terminated process are assigned a new parent process ID. Note: the termination of a parent does not directly terminate its children. 5. If the implementation supports the SIGCHLD signal, a SIGCHLD is sent to the parent. 6. Several job control signals are sent.

  為何在一個(gè)fork的子進(jìn)程分支中使用_exit函數(shù)而不使用exit函數(shù)? ‘exit()’與‘_exit()’有不少區(qū)別在使用‘fork()’,特別是‘vfork()’時(shí)變得很 突出。

  ‘exit()’與‘_exit()’的基本區(qū)別在于前一個(gè)調(diào)用實(shí)施與調(diào)用庫(kù)里用戶狀態(tài)結(jié)構(gòu)(user-mode constructs)有關(guān)的清除工作(clean-up),而且調(diào)用用戶自定義的清除程序 (自定義清除程序由atexit函數(shù)定義,可定義多次,并以倒序執(zhí)行),相對(duì)應(yīng),_exit函數(shù)只為進(jìn)程實(shí)施內(nèi)核清除工作。 在由‘fork()’創(chuàng)建的子進(jìn)程分支里,正常情況下使用‘exit()’是不正確的,這是 因?yàn)槭褂盟鼤?huì)導(dǎo)致標(biāo)準(zhǔn)輸入輸出(stdio: Standard Input Output)的緩沖區(qū)被清空兩次,而且臨時(shí)文件被出乎意料的刪除(臨時(shí)文件由tmpfile函數(shù)創(chuàng)建在系統(tǒng)臨時(shí)目錄下,文件名由系統(tǒng)隨機(jī)生成)。在C++程序中情況會(huì)更糟,因?yàn)殪o態(tài)目標(biāo)(static objects)的析構(gòu)函數(shù)(destructors)可以被錯(cuò)誤地執(zhí)行。(還有一些特殊情況,比如守護(hù)程序,它們的父進(jìn)程需要調(diào)用‘_exit()’而不是子進(jìn)程;適用于絕大多數(shù)情況的基本規(guī)則是,‘exit()’在每一次進(jìn)入‘main’函數(shù)后只調(diào)用一次。) 在由‘vfork()’創(chuàng)建的子進(jìn)程分支里,‘exit()’的使用將更加危險(xiǎn),因?yàn)樗鼘⒂绊懜高M(jìn)程的狀態(tài)。

  #include 《sys/types.h》; #include 《stdio.h》 int glob = 6; /* external variable in initialized data */ int main(void) { int var; /* automatic variable on the stack */ pid_t pid; var = 88; printf(“before vfork\n”; /* we don‘t flush stdio */ if ( (pid = vfork()) 《 0) printf(“vfork error\n”; else if (pid == 0) { /* child */ glob++; /* modify parent‘s variables */ var++; exit(0); /* child terminates */ //子進(jìn)程中最好還是用_exit(0)比較安全。 } /* parent */ printf(“pid = %d, glob = %d, var = %d\n”, getpid(), glob, var); exit(0); } 在Linux系統(tǒng)上運(yùn)行,父進(jìn)程printf的內(nèi)容輸出:pid = 29650, glob = 7, var = 89

  子進(jìn)程 關(guān)閉的是自己的, 雖然他們共享標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)出錯(cuò)等 “打開(kāi)的文件”, 子進(jìn)程exit時(shí),也不過(guò)是遞減一個(gè)引用計(jì)數(shù),不可能關(guān)閉父進(jìn)程的,所以父進(jìn)程還是有輸出的。

  但在其它UNIX系統(tǒng)上,父進(jìn)程可能沒(méi)有輸出,原 因是子進(jìn)程調(diào)用了e x i t,它刷新關(guān)閉了所有標(biāo)準(zhǔn)I / O流,這包括標(biāo)準(zhǔn)輸出。雖然這是由子進(jìn)程執(zhí)行的,但卻是在父進(jìn)程的地址空間中進(jìn)行的,所以所有受到影響的標(biāo)準(zhǔn)I/O FILE對(duì)象都是在父進(jìn)程中的。當(dāng)父進(jìn)程調(diào)用p r i n t f時(shí),標(biāo)準(zhǔn)輸出已被關(guān)閉了,于是p r i n t f返回- 1。

  在Linux的標(biāo)準(zhǔn)函數(shù)庫(kù)中,有一套稱作“高級(jí)I/O”的函數(shù),我們熟知的printf()、fopen()、fread()、fwrite()都在此 列,它們也被稱作“緩沖I/O(buffered I/O)”,其特征是對(duì)應(yīng)每一個(gè)打開(kāi)的文件,在內(nèi)存中都有一片緩沖區(qū),每次讀文件時(shí),會(huì)多讀出若干條記錄,這樣下次讀文件時(shí)就可以直接從內(nèi)存的緩沖區(qū)中讀取,每次寫文件的時(shí)候,也僅僅是寫入內(nèi)存中的緩沖區(qū),等滿足了一定的條件(達(dá)到一定數(shù)量,或遇到特定字符,如換行符和文件結(jié)束符EOF), 再將緩沖區(qū)中的 內(nèi)容一次性寫入文件,這樣就大大增加了文件讀寫的速度,但也為我們編程帶來(lái)了一點(diǎn)點(diǎn)麻煩。如果有一些數(shù)據(jù),我們認(rèn)為已經(jīng)寫入了文件,實(shí)際上因?yàn)闆](méi)有滿足特 定的條件,它們還只是保存在緩沖區(qū)內(nèi),這時(shí)我們用_exit()函數(shù)直接將進(jìn)程關(guān)閉,緩沖區(qū)中的數(shù)據(jù)就會(huì)丟失,反之,如果想保證數(shù)據(jù)的完整性,就一定要使用exit()函數(shù)。

  Exit的函數(shù)聲明在stdlib.h頭文件中。

  _exit的函數(shù)聲明在unistd.h頭文件當(dāng)中。

  下面的實(shí)例比較了這兩個(gè)函數(shù)的區(qū)別。printf函數(shù)就是使用緩沖I/O的方式,該函數(shù)在遇到“\n”換行符時(shí)自動(dòng)的從緩沖區(qū)中將記錄讀出。實(shí)例就是利用這個(gè)性質(zhì)進(jìn)行比較的。

  exit.c源碼

  #include 《stdlib.h》 #include 《stdio.h》 int main(void) { printf(“Using exit.。。\n”); printf(“This is the content in buffer”); exit(0); }

  輸出信息:

  Using exit.。。

  This is the content in buffer

  #include 《unistd.h》 #include 《stdio.h》 int main(void) { printf(“Using exit.。。\n”); //如果此處不加“\n”的話,這條信息有可能也不會(huì)顯示在終端上。 printf(“This is the content in buffer”); _exit(0); }

  則只輸出:

  Using exit.。。

  說(shuō)明:在一個(gè)進(jìn)程調(diào)用了exit之后,該進(jìn)程并不會(huì)馬上完全消失,而是留下一個(gè)稱為僵尸進(jìn)程(Zombie)的數(shù)據(jù)結(jié)構(gòu)。僵尸進(jìn)程是一種非常特殊的進(jìn)程,它幾乎已經(jīng)放棄了所有的內(nèi)存空間,沒(méi)有任何可執(zhí)行代碼,也不能被調(diào)度,僅僅在進(jìn)程列表中保留一個(gè)位置,記載該進(jìn)程的退出狀態(tài)等信息供其它進(jìn)程收集,除此之外,僵尸進(jìn)程不再占有任何內(nèi)存空間。

  #include 《stdio.h》;

  int main() { printf(“%c”, ‘c‘); _exit(0); }

  上面就是Linux系統(tǒng)中exit與_exit的區(qū)別介紹了,它們的區(qū)別主要體現(xiàn)在函數(shù)庫(kù)中的定義,大部分情況還是相同的,你了解了嗎?

標(biāo)簽 命令 exit

發(fā)表評(píng)論

0

沒(méi)有更多評(píng)論了

評(píng)論就這些咯,讓大家也知道你的獨(dú)特見(jiàn)解

立即評(píng)論

以上留言僅代表用戶個(gè)人觀點(diǎn),不代表系統(tǒng)之家立場(chǎng)

其他版本軟件

熱門教程

人氣教程排行

Linux系統(tǒng)推薦

掃碼關(guān)注
掃碼關(guān)注

掃碼關(guān)注 官方交流群 軟件收錄