main函數
當內核使用一個exec函數執行C程序時,在調用main函數之前先調用一個特殊的啓動例程,可執行程序將此例程指定爲起始地址。啓動例程從內核獲取命令行參數和環境變量,然後爲調用main函數做好準備。
進程終止
進程終止的方式有8種,前5種爲正常終止,後3種爲異常終止:
1.從main函數返回;
2.調用exit函數;
3.調用_exit或_Exit;
4.最後一個線程從啓動例程返回;
5.最後一個線程調用pthread_exit;
6.調用abort函數;
7.接到一個信號終止;
8.最後一個線程對取消請求做出響應。
(1)exit 函數
#include<stdio.h>
void exit(int status);
void _Exit(int status);
#include<unistd.h>
void _exit(int status);
這三個函數用於正常終止一個程序,_exit和_Exit立即進入內核,而exit則要先做一些清理工作(調用執行各終止處理程序,關閉所有標準I/0流),再進入內核。exit(0)表示程序正常,exit(1)/exit(-1)表示程序異常退出。三個程序所帶的整數型參數稱爲終止狀態或退出狀態,如果(a)調用這些函數不帶參數,(b)main函數中的return語句無返回值,(c)main函數沒有聲明返回類型爲整型,則進程的終止狀態是未定義的。main函數返回一個整型值與該值調用exit是等價的。
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("this process will exit\n");
exit(0);
printf("never be displayed\n");
}
運行結果如下圖:
(2)atexit 函數
#include<stdio.h>
int atexit(void(*fun)(void));
一個進程可以登記若干個函數,這些函數有exit自動調用,這些函數被稱爲終止處理函數,atexit函數可以登記這些函數。exit調用終止處理函數的順序和atexit登記的順序相反,如果一個函數被多次登記,也會被多次調用。
#include<stdio.h>
#include<stdlib.h>
void fiun1()
{
printf("fun1被調用\n");
}
void fiun2()
{
printf("fun2被調用\n");
}
void fiun3()
{
printf("fun3被調用\n");
}
int main()
{
atexit(fun1);
atexit(fun2);
atexit(fun3);
printf("進程結束\n");
}
運行結果如下圖: