進程的啟動
當內(nèi)核執(zhí)行C程序時(使用exec函數(shù))在調(diào)用main前先調(diào)用一個特殊的啟動例程奢方。可執(zhí)行程序文件將此啟動例程指定位程序的起始地址躬它。啟動例程從內(nèi)核取得命令行參數(shù)和環(huán)境變量值网持,然后為按上述方式調(diào)用main函數(shù)做好安排。
image.png
進程的終止
正常終止
- 從main返回
- 調(diào)用exit
- 調(diào)用_exit或_Exit
- 最后一個線程從其啟動例程返回
- 從最后一個線程調(diào)用pthread_exit
異常終止
- 調(diào)用abort
- 接到一個信號
- 最后一個線程對取消請求做出響應(yīng)
- 進程通過main函數(shù)return返回吟温,會調(diào)用C庫中的exit函數(shù),exit函數(shù)首先調(diào)用各終止處理函數(shù)突颊,然后關(guān)閉(通過fclose)所有打開流鲁豪,然后調(diào)用的_exit退出。
- 如果直接調(diào)用_exit不會調(diào)用終止處理函數(shù)和關(guān)閉被打開的流律秃。
- 若程序調(diào)用exec函數(shù)族中的任一函數(shù)爬橡,則將清除所有已注冊的終止處理函數(shù)。
- 進程收到信號時棒动,如果沒有注冊對應(yīng)的信號處理函數(shù)糙申,那么內(nèi)核就會執(zhí)行信號的默認動作,一般是直接終止進程船惨。
1. 演示 return, exit, _exit 的區(qū)別
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void term_fun1(void){
printf("first term function\n");
}
void term_fun2(void){
printf("second term function\n");
}
void term_fun3(void){
printf("third term function\n");
}
int main(int argc, char* argv[]){
if (argc < 3){
fprintf(stderr, "usage: %%s file[exit|_exit|return]\n");
exit(1);
}
atexit(term_fun1);
atexit(term_fun2);
atexit(term_fun3);
FILE *fp = fopen(argv[1], "w");
fprintf(fp, "hello world!\n");
if(!strcmp(argv[2], "exit")){
exit(0);
} else if (!strcmp(argv[2], "_exit")){
_exit(0);
} else if (!strcmp(argv[2], "return")){
return 0;
} else {
fprintf(stderr, "usage: %%s file[exit|_exit|return]\n");
}
return 0;
}
# return 調(diào)用終止處理程序柜裸,刷新標準I/O緩存
LEOQYANG-MC1:ch07 leoqyang$ ./process_term process_term.txt return
third term function
second term function
first term function
LEOQYANG-MC1:ch07 leoqyang$ cat process_term.txt
hello world!
# exit 調(diào)用終止處理程序,刷新標準I/O緩存
LEOQYANG-MC1:ch07 leoqyang$ ./process_term process_term.txt exit
third term function
second term function
first term function
LEOQYANG-MC1:ch07 leoqyang$ cat process_term.txt
hello world!
# _exit 不執(zhí)行終止處理程序粱锐,不刷新標準I/O緩存疙挺,直接退出
LEOQYANG-MC1:ch07 leoqyang$ ./process_term process_term.txt _exit
LEOQYANG-MC1:ch07 leoqyang$ cat process_term.txt
LEOQYANG-MC1:ch07 leoqyang$
2. 演示收到信號的情況
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
static void callback(void){
printf("callback\n");
}
int main(int argc, char * argv[]){
if (argc < 2){
fprintf(stderr, "usage: filename\n");
exit(1);
}
FILE *fp = fopen(argv[1], "w");
fprintf(fp, "hello world!\n");
atexit(callback);
while(1) {
sleep(1);
}
printf("main exit\n");
return 0;
}
# 執(zhí)行killall 3_3_2 不執(zhí)行終止處理程序,不刷新標準I/O緩存怜浅,直接退出
LEOQYANG-MC1:ch3 leoqyang$ ./3_3_2 3_3_2.txt
Terminated: 15
LEOQYANG-MC1:ch3 leoqyang$ cat 3_3_2.txt
LEOQYANG-MC1:ch3 leoqyang$
參考
- 第5章 進程環(huán)境(2)_進程的啟動和終止
- Unix環(huán)境高級教程 第7章
- Linux環(huán)境編程 第3章