首先我們瞭解下atexit函數:
函數名:atexit
頭文件:#include<stdlib.h>
功 能 : 註冊終止函數(即main執行結束後調用的函數)
原型 : void atexit(void (*func)(void));
說明:atexit()用來設置一個程序正常結束前調用的函數. 當程序通過調用exit()或從main 中返回時, 參數function 所指定的函數會先被調用, 然後才真正由exit()結束程序。
調用順序: 在atexit(f)調用之前被靜態分配的對象的析構函數將在f()的調用之後被調用。在一個atexit(f)調用之後建立的這種對象的析構函數將在f的調用之前被調用。引自《The C++ Programming Language》(Bjarne Stroustrup)。
進程終止的方法有8種,如下所示,其中前5種是正常的方法,後面的3種方法是異常終止。
- 從 main 返回
- 調用 exit
- 調用 _exit 或 _Exit
- 最後一個線程從其啓動例程返回
- 最後一個線程調用pthread_exit
- 調用 abort
- 接到一個信號並終止
- 最後一個線程對取消請求做出響應
下面看下atexit函數的作用例子:
#include<iostream>
#include<stdlib.h>
using namespace std;
int atexit(void (*function)(void));
void func1(void), func2(void), func3(void);
int main(int argc, char* argv[])
{
atexit(func1);
atexit(func2);
atexit(func3);
cout << "this is main..." << endl;
//exit(0);
//_exit(0);
//_Exit(0);
return 0;
}
void func1()
{
cout << "func1..." << endl;
}
void func2()
{
cout << "func2..." << endl;
}
void func3()
{
cout << "func3..." << endl;
}
運行上面的程序:
發現:首先在main函數返回(return 0;)之後,程序還在繼續運行,並且執行的順序和我們在main函數中登記的順序是相反的。
然後我們分別執行main函數中的exit()、_exit()、 _Exit() 函數來終止進程,發現,執行exit()時程序的運行效果跟上面的運行效果是一致的,而_exit()、 _Exit() 的執行結果如下所示:
上面的兩種不同的結果,說明:
exit()和_exit()以及_Exit()函數的本質區別是是否立即進入內核,_exit()以及_Exit()函數都是在調用後立即進入內核,而不會執行一些清理處理,但是exit()則會執行一些清理處理,這也是爲什麼會存在atexit()函數的原因,因爲exit()函數需要執行清理處理,需要執行一系列的操作,這些終止處理函數實際上就是完成各種所謂的清除操作的實際執行體。