2. 进程启动和终止
2.1 C程序启动过程
(1)启动例程
①是一段程序代码,放置在/lib/libc.so.***中。编译器在编译时会将启动例程的代码编译进可执行文件中。
②可执行程序将这段嵌入的启动例代码指代为程序的起始地址。
③当内核执行C程序时(使用exec函数),在调用main前先执行启动例程代码。
(2)启动例程的作用
①搜集命令行的参数传递给main函数中的argc和argv
②搜集环境信息构建环境表并传递给main函数
③登记进程的终止函数
2.2 进程终止
| 进程终止 | 主要方式 | 
| 正常终止 | ①从main函数返回;②调用exit(标准C库函数); ③调用_exit或_Exit(系统调用); ④最后一个线程从其启动例程返回。 ⑤最后一个线程调用pthread_exit | 
| 异常终止 | ①调用abort;②接到一个信号并终止; ③最后一个线程对取消请求做出响应 | 
| 进程返回 | ①通常程序运行成功返回0,否则返回非0。②在shell中可以通过echo $?查看进程返回值。 | 
2.3 相关函数
(1)exit函数
| 头文件 | #include<stdlib.h> | 
| 函数 | void exit(int status); void _Exit(int status); void _exit(int status); //#include <unistd.h> | 
| 功能 | 终止进程 | 
| 备注 | (1)_exit和_Exit立即进入内核。 (2)exit会先执行一些清理处理(包括调用执行各终止处理程序,关闭所有标准I/O流等),然后再进入内核。 | 
(2)atexit函数
| 头文件 | #include<stdlib.h> | 
| 函数 | int atexit(void(*function)(void)); | 
| 返回值 | 若成功则为0,若出错则为-1 | 
| 功能 | 向内核登记终止处理程序(exit handler) | 
| 备注 | (1)每个启动的进程都默认登记了一个标准的终止函数。 (2)终止函数在进程终止时释放进程所占用的一些资源。 (3)登记的多个终止函数执行顺序是以栈的方式执行的,即先登记的后执行。 | 
【编程实验】终止处理函数
//process_term.c
#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 funciton\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函数向内核登记终止函数 //注意:注册终止函数的顺序为func1->fun2->fun3,函数被调用顺序fun3->fun2->fun1 atexit(term_fun1); atexit(term_fun2); atexit(term_fun3); FILE* fp = fopen(argv[1], "w"); fprintf(fp, "hello world!\n"); //fprintf带缓存,调用exit或return时会被 //流会被关闭,即会被写入指定的文件中。 if(!strcmp(argv[2], "exit")){ exit(0); //标准C的库函数 }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", argv[0]); } return 0; } /*输出结果: [root@localhost 5.process]# bin/process_term term.txt return //正常退出(调用终止函数和刷新缓存) third term function second term funciton first term function [root@localhost 5.process]# cat term.txt hello world! [root@localhost 5.process]# bin/process_term term.txt exit //正常退出(调用终止函数和刷新缓存) third term function second term funciton first term function [root@localhost 5.process]# cat term.txt hello world! [root@localhost 5.process]# bin/process_term term.txt _exit //异常退出(不调用终止函数和刷新缓存) [root@localhost 5.process]# cat term.txt [root@localhost 5.process]# bin/process_term term.txt quit usage: bin/process_term file [exit|_exit|return] third term function second term funciton first term function [root@localhost 5.process]# cat term.txt hello world! [root@localhost 5.process]# */
2.4 C程序的启动和终止
(1)进程的终止
 
 
(2)终止方式的区别
| 
 | return | exit() | _exit/_Exit | 
| 是否刷 新标准I/O缓存 | 是 | 是 | 否 | 
| 是否自动调用终止函数 | 是 | 是 | 否 | 
(3)说明
①exit首先调用各终止处理程序,然后按需要多次调用fclose关闭所有打开流。而调用_exit或_Exit则将直接进入内核,不会调用终止处理函数和关闭被打开的流。
②POSIX标准规定,如果程序调用exec函数族中的任一个函数,则将清除所有己安装的终止处理程序。
③内核使程序执行的唯一方法是调用一个exec函数。进程自愿终止的唯一方未能是显式或隐式地(通过调用exit)来调用_exit或_Exit。进程序也可以非自愿地由一个信号使其终止。
原文:http://www.cnblogs.com/5iedu/p/6353938.html