一、进程退出的场景
- 1.代码运行完毕,结果正确
- 2.代码运行完毕,结果不正确
- 3.代码异常终止
进程退出时,一般而言只有父进程关心子进程的退出情况。
进程退出码
在Linux中,操作系统最关心的是一个进程的代码运行完毕后,为什么结果不正确?
而不关心结果为什么正确。
举个生活的例子:
你考试考了100分回家,跟你爸说:“老爸,我考试考了100分。”
你老爸会关心你为什么考了100分吗?
如果你考了10分回家,你老爸一定问你为什么考了10分。
操作系统也是如此。
一个进程正常运行结束后,结果正确时的退出码为0;
6 int main()
7 {
8 printf("模拟程序正常结束,结果正确\n");
9 return 0;
10 }
使用echo $?
命令查看最近一个运行成功的程序的退出码。
为了更正确理解上面那句话,这里修改代码,直接return 12;
此时上一个程序运行退出码为12,再echo $?
一次:
结果变成了0,因为上一次运行成功的进程是echo
命令成功运行了。
一个程序运行结果正确/不正确,是以退出码来判断的。
errno全局变量
errno是c语言提供的一个全局变量。
代表最近一次执行程序时发生错误的错误码。
注意:由于程序的退出码0代表成功,所以该错误码不可能为0。
7 int main()
8 {
9 int *p =(int*)malloc(sizeof(int)*1000*1000*1000*4);
10 int ret =0;
11 if(p == NULL)
12 {
13 printf("%d :%s\n",errno,strerror(errno));
14 ret = errno;
15 }
16 return errno;
17 }
以该代码为例,申请大量空间,必然会失败。
此时需要查看失败原因,就可以使用对应的errno错误码,并将退出码对应的错误信息打印出来。
此时errno错误码还可以作为退出码返回给父进程。
这便是errno的意义。
进程异常退出,退出码有意义吗
举个简单的例子:小胖考试考了90分,但是他作弊了。
小胖回家跟爸爸说 : “老爸,我考了90分”。老爸高兴得想给儿子一个亲亲,小胖又说:“老爸,我作弊了”。此时老爸恨不得给儿子一个大嘴巴子。
在这个过程,进程异常退出,就好比小胖作弊了。一旦作弊了,那么最终成绩将毫无意义。
所以进程异常退出,退出码毫无意义。
并且,如果一个进程异常退出,很有可能无法执行到返回退出码这一条语句。程序可能会直接终止。
可是不关心退出码,也要关心进程为什么异常,出了什么异常。
其实,进程退出异常,本质是进程收到了对应的信号。
总结:父进程先关心子进程是否异常,再关心退出码。
二、进程终止
进程退出的常见方法:
- 1.return返回
- 2.exit函数退出
- 3._exit系统调用退出
exit函数
exit函数直接将进程终止,并刷新缓冲区。
_exit系统调用
_exit函数直接将进程终止,不刷新缓冲区。
- 两者之间的关系:
1.exit函数内部其实是调用_exit() + fflush()函数的。
2.exit是c语言对操作系统提供的_exit系统调用进行封装,而_exit函数是系统提供的接口。
return语句如果在其他函数内部,是退出该函数。
如果在main函数内部,才是进程退出。