终止的结果
进程终止后,释放申请的相关内核数据结构和对应的数据和代码。本质就是释放系统资源
终止的场景
- 代码跑完,结果正确
- 代码跑完,结果不正确
- 代码没有跑完,程序崩溃
进程常见退出方法
正常退出:
1.main返回
2.eixt
3._exit
异常退出:
crtl+c,信号终止
main函数返回的意义
以前我们main函数里都会写一个返回0,作为main函数的返回值。其实,main函数的返回值是返回给上一级进程,用来评判该进程执行结果用的,因此,main函数的返回值不一定是0,随便运行一个代码,写上返回0试试
1 test: test.c
2 gcc -o $@ $^
3 .PHONY:clean
4 clean:
5 rm -f test
makefile里$@表示编译所有.c的文件
如何查看返回值
可以通过
echo $?
来获取最近的一次返回值
返回0,将return的值改为10再看看
改为10后,返回值就是10
返回值0表示程序正常终止,结果正确。非0值表示结果不正确
非零返回的意义
非零值有无数个,不同的非零值可以表示不同的错误原因,可以方便定位错误的原因。那具体每个返回值代表什么,可以通过strerror来解析
可以用一个for循环打印前150个错误信息
for(;i<150;i++)
7 {
8 printf("%s\n", strerror(i));
9 }
打印到了133个就没有了,上面的就是常见错误。0表示成功运行,其他每一个都有表示的意义
我们用ls命令,随便传入一段参数看看返回值
这正好对应了上面的错误码和信息,ls命令将错误码的结果解析了出来,显示给了用户
知道了错误码可以表示错误信息,那我们自己也可以定义一个返回值来标识自己的程序运行出错的结果和原因
6 int i = 0;
7 int sum = i + 50;
8 if (sum != 50)
9 {
10 printf("计算错误\n");
11 return 1;
12 }
如果计算错误就返回1
exit函数
exit可以在任何地方调用退出程序,也可以传出返回值
#include <unistd.h>
void exit(int status);
在代码中用exit函数,参数填入数字试试
1 #include <stdio.h>
2 #include <string.h>
3
4 void fun()
5 {
6 exit(222);
7 }
8 int main()
W> 9 {
10 int i = 0;
11 fun();
12 // for(;i<150;i++)
13 // {
14 // printf("%s\n", strerror(i));
15 // }
16 return 10;
17 }
返回值是exit函数的222,不是return的结果,exit后,程序已经终止了
exit可以在任何位置传出返回值,return只能在main函数传出返回值
_exit
和exit不同的是,_exit是系统调用,exit是库函数
#include <unistd.h>
void _exit(int status);
参数:status 定义了进程的终止状态,父进程通过wait获取该值
将fun函数的内容修改一下
5 void fun()
6 {
7 printf("你好吗");
8 exit(222);
9 }
将exit换位_exit函数
这时什么都没有输出
exit函数做了什么
1.执行用户通过atexit或on_exit定义的清理函数
2.关闭所有打开的流,所有的缓存数据均被写入
3.调用_exit
exit函数内部调用了_exit,所以,_exit是系统调用,exit是对它的封装。_exit并不会刷新缓冲区数据
那么缓冲区是谁维护的
缓冲区是库函数维护的,如果是系统的,那系统调用_exit应该也会刷新缓冲区,但事实不能。所以是c标准库给我们维护的