1.进程终止时,操作系统做了什么
释放进程申请的相关数据结构和对应的代码和数据,本质就是释放系统资源。
2.终止进程的常见情况
a.代码跑完,结果正确
b.代码跑完,结果不正确
c.代码没有跑完,程序崩溃
前两种情况,main函数是有返回值的,这个返回值称为进程的退出码。我们一般把返回值设为0。
main函数返回值的意义:返回值给上一级进程,用来评判该进程执行结果用的。
返回值的非零值有无数个,不同的非零值就可以标识不同的错误原因->给我们的程序在运行结束之后,结果不正确时,方便定位错误原因的细节。
strerror可以将错误码或退出码转换成字符串描述的方案
举例使用:
5 int main()
6 {
7 for(int i=0;i<150;i++)
8 {
9 cout<<i<<":"<<strerror(i)<<endl;
10 }
11 return 0;
12 }
[weixing@VM-12-9-centos 6.6]$ ./a.out
0:Success
1:Operation not permitted
2:No such file or directory
3:No such process
4:Interrupted system call
5:Input/output error
......
echo $?获取最近一个进程执行完毕的退出码
举例:
[weixing@VM-12-9-centos 6.6]$ ls sasxaxasixmjsj.txt
ls: cannot access sasxaxasixmjsj.txt: No such file or directory
[weixing@VM-12-9-centos 6.6]$ echo $?
2
[weixing@VM-12-9-centos 6.6]$ kill -9 12345
-bash: kill: (12345) - No such process
[weixing@VM-12-9-centos 6.6]$ echo $?
1
程序崩溃的时候,退出码是无意义。因为此时退出码对应的return语句没有被执行。
3.进程常见退出方法
正常退出:
1.main函数内,return语句,就是终止进程的。即return+退出码。
2.调用exit函数
3.调用_exit函数
区别exit和_exit函数
exit最后也会调用_exit, 但在调用_exit之前,还做了其他工作:
1. 执行用户通过 atexit或on_exit定义的清理函数。
2. 关闭所有打开的流,所有的缓存数据均被写入
3. 调用_exit
举例:
8 int main()
9 {
10 printf("hello world");
11 exit(0);
12 }
运行起来之后:
[weixing@VM-12-9-centos 6.6]$ ./a.out
hello world[weixing@VM-12-9-centos 6.6]$
8 int main()
9 {
10 printf("hello world");
11 _exit(0);
12 }
运行起来之后:
[weixing@VM-12-9-centos 6.6]$ ./a.out
[weixing@VM-12-9-centos 6.6]$
从这个例子可以窥见:printf -\n数据是保存在缓冲区中的,这个缓冲区不是在OS内部的,因为如果是在OS内部,_exit()函数也能刷新出来。这个缓冲区是由C标准库维护的(以后讲)。
异常退出
在信号部分讲解。