进程终止:
进程终止的本质就是释放系统资源,就是释放进程申请的相关数据结构和对应的数据和代码。
进程的退出场景:
1、代码运行完毕,结果正确
2、代码运行完毕,结果不正确
3、代码异常终止
当我们在写C语言代码或者C++代码时,通常在main函数的最后会return 0
main函数是我们程序的入口。main函数的返回值是让main函数的父进程知道自己最终运行的结果是怎么样。
c
int main()
{
return 0;
}
main函数的返回值本质就是退出码
1、return 0:表示代码运行完毕,结果正确(正常退出)
2、return 非0值:如 -1、2、3等,表示代码运行完毕,结果不正确(正常退出,但结果异常)

运行该程序,结果如下:

查看退出码
echo $?查看上一个执行的进程(命令 / 程序)的退出码

可以查看到程序mytest的退出码为0,正常退出。

该代码是以只读的方式打开当前目录下的log.txt文件,成功打开时就打印读取文件内容,这是我们期望的结果。
(注:当前目录下没有该文件,所以该程序必定打开失败)
运行该程序,并查看该进程的退出码。

退出码非0,正常退出但结果异常。
现在我们就已经有了一个概念。当进程的退出码为0时,代表进程正常退出。
退出码非0时就代表着进程正常退出,但是结果有点问题。
当进程的退出码为非0时,就可以用非0值来表示不同出问题的情况
但我们人更容易接受字符串类型的错误表示。
比如"这是某某错误"
为了方便我们观察,在C标准库中提供了错误码和错误码对应的字符串描述
strerror用来把错误码转换成对应的描述。
但是我们不知道在Linux系统中有多少个退出码。我们就先随便写一个数字如140.然后写一个循环来循环打印退出码和其对应的描述。

运行该程序,下面的长图不用仔细看。只是为了打印演示。

观看最后几行,图片如下:

可以发现退出码从0开始一直到133,在Linux系统中一共134个退出码。
在看开头,图片如下:

记录着退出码对应的信息。
这些时系统的退出码。我们在编写程序时也可以自定义退出码




这里发现我们自定义的退出码明明是12937,但是最终运行却是137.
这是因为在 Linux 系统中,进程的退出码被限制在 0 到 255 之间(即一个无符号 8 位整数的范围)。当你返回的数值超过这个范围时,系统会自动对其进行 模 256 运算,只保留低 8 位的值作为最终的退出码。
12937 % 256 = 137

上面的代码模拟出现异常的情况。可以发现会进入if语句,然后发生异常,最终返回77。
运行该程序

系统提示了异常,现在查看该进程的退出码。

发现最终查看到的退出码并不是我们所写的77,而是136.
这里就直接把结论告诉大家,但进程发生异常时,该进程的退出码就没有意义。
这里举个例子:
一个猴子去考试,考试结束后它最终考了满分。代表程序正常退出。
当它出了些错误,考试结束后最终的分数为50.代表程序正常退出,但结果不正确。
当它在考试中作弊时,被发现了。直接丢出考场。此时猴子的成绩就没有意义了。
进程一旦出现异常,一般是进程收到了信号(这句话可以先不用理解,后面会讲到。这里先写出来让大家看到)
进程常见的退出方式:
1、在main函数中使用return
2、调用exit
3、调用_exit
1、在main函数中return我们平常使用的很多,大家肯定都能理解。
2、exit:作用和return相同。都会刷新缓冲区。
3、_exit:当进程调用_exit时,该进程会直接退出,不刷新缓冲区。
例子1:

运行上面的代码并查看该进程的退出码。

例子2:

运行上面的代码并查看该进程的退出码。

能够看出上面两个例子中exit的用法和return相同
现在把代码中的exit替换成_exit

运行上面的代码并查看该进程的退出码。

可以发现_exit也能做到让进程退出。
现在来讲一下exit和_exit的区别
exit是C语言提供
_exit是系统提供
下面用代码演示两者的区别。

上面的代码中,printf语句把字符串cccc放入缓冲区,由于最后有\n换行,会立即把字符串cccc从缓冲区刷新出来,直接打印字符串cccc,然后休眠2秒。程序结束。
运行上面的代码,查看该进程的退出码。

此时是先打印字符串cccc然后休眠。
2秒后:

查看该进程的退出码:

现在把\n去掉

此时会出现的状况是,把字符串cccc放入缓冲区,由于没有\n,所以不会立即刷新缓冲区。
休眠2秒之后执行exit,
exit会先刷新缓冲区然后再进程退出。

此时字符串cccc已经放入缓冲区,但是没有刷新出来。等待2秒之后

exit刷新了缓冲区,并让该进程退出。
查看该进程的退出码:

换成_exit

该进程会先将字符串cccc放入缓冲区中,因为有\n所以立即刷新缓冲区,字符串cccc被打印出来,然后休眠2秒。_exit让进程退出

休眠2秒之后:

查看退出码:

去掉\n

会先把cccc放入缓冲区中,因为没有\n所以不会立即刷新缓冲区,字符串cccc也就打印不出来。
运行到sleep(2)就开始休眠2秒。
当休眠结束之后就会运行_exit,但是_exit不会去刷新缓冲区。所以最终看到的结果就是,等待两秒之后进程结束。

休眠结束后:

查看退出码:
