天天看點

exit()、_exit()、return 的差別詳解_exit(0)與exit(0)

_exit(0)與exit(0)

  • exit ():調用exit函數之後,它首先會執行一系列的清理處理,包括調用執行各終止處理程式,關閉所有标準IO流等,然後進入核心。
  • _exit ():與exit不同的是,它不進行清理工作而直接進入核心。此函數由POSIX.1說明,放在unistd.h裡面。
  • return :函數傳回傳遞參數的,當然在main函數裡就是結束程序了。也就是說,在main()裡面,你可以用return n,也能夠直接用exit(n)來做。

    驗證代碼如下:

#include <stdlib.h>

#include<unistd.h>
#include <stdio.h>
int main()
{
    printf("hello world!");
    _exit(0);
    //exit(0);
}

           

結果如下:

exit()、_exit()、return 的差別詳解_exit(0)與exit(0)

細心的讀者可以發現:

此時終端并沒有列印hello world!

而重定位輸出到檔案後,依舊沒有檢視到列印資訊。

而我們不妨将測試代碼中的_exit(0)改成exit(0)試試

結果如下:

exit()、_exit()、return 的差別詳解_exit(0)與exit(0)

你會發現終端列印出資訊,同時重定位也有資訊。

_exit(0)與exit(0)解釋如下:

由于printf函數是行緩沖的(因為它要往終端輸出資料),而且要列印的字元串不帶換行符,是以在它沒有遇到換行符或者沒有填滿緩沖區之前不會進行實際的IO操作,而在_exit函數有立即進入核心沒有處理IO緩沖區,是以我們在終端上看不到hello world語句。當我們調用exit()函數時,在終端看到了hello world。

return、_exit()與exit的差別:

頭檔案:

exit:#include<stdlib.h>

_exit:#include<unistd.h>

_exit()函數:直接使程序停止運作,清除其使用的記憶體空間,并銷毀其在核心中的各種資料結構;

exit()函數則在這些基礎上作了一些包裝,在執行退出之前加了若幹道工序。

exit()函數與_exit()函數最大的差別就在于 exit()函數在調用 exit 系統調用之前要檢查檔案的打開情況,把檔案緩沖區中的内容寫回檔案。

exit是系統調用級别的,它表示了一個程序的結束,它将删除程序使用的記憶體空間,同時把錯誤資訊傳回父程序。通常情況:exit(0)表示程式正常, exit(1)和exit(-1)表示程式異常退出,exit(2)表示系統找不到指定的檔案。在整個程式中,隻要調用exit就結束。

return是語言級别的,它表示了調用堆棧的傳回;return是傳回函數值并退出函數,通常0為正常退出,非0為非正常退出

退出過程

  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()、_exit()、return 的差別詳解_exit(0)與exit(0)

繼續閱讀