进程退出场景

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码异常终止

进程常见退出方法

可以通过 echo $? 查看进程退出码。

Linux 下进程的退出分为正常退出和异常退出两种:

1.正常退出

  • 在main()函数中执行return
  • 调用exit()函数
  • 调用_exit()函数

2.异常退出

  • 调用abort函数
  • 进程收到某个信号,而该信号使进程终止

不管是哪种退出方式,系统最终都会执行内核中的同一代码。这段代码用来关闭进程所用已打开的文件描述符,释放它所占用的内存和其他资源。

分析退出码

1.正常退出

echo $? 回显0,进程正常退出.

2.异常退出

 echo $? 回显非0,进程异常退出.
 
 ctrl + c,信号终止

_exit函数

 #include <unistd.h>
 void _exit(int status);
 
参数:status定义了子进程的终止状态,父进程通过wait来获取该值
  • 说明:虽然status是int,但是仅有低8位可以被父进程所用。所以_exit(-1)时,在终端执行$? 发现返回值 是255。

exit函数

#include <unistd.h> 
void exit(int status);

在调用exit之前,还做了其他工作:

  • . 执行用户通过 atexit或on_exit定义的清理函数。
  • 关闭所有打开的流,所有的缓存数据均被写入
  • 调用_exit

进程终止_文件描述符

_exit函数与exit()函数的区别(上图)

  1. _exit()执行后会立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。
  2. 调用_exit()函数时,其会关闭进程所有的文件描述符,清理内存,以及其他一些内核清理函数,但不会刷新流(stdin 、stdout、stderr……)。exit()函数是在_exit()函数上的一个封装,它会调用_exit,并在调用之前先刷新流。
  3. .exit()函数与_exit()函数最大的区别就在于,exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区的内容写回文件。

看下面的例子:
进程终止_进程退出_02
输出结果:
进程终止_exit函数_03
进程终止_文件描述符_04
进程终止_进程退出_05

return退出

return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返回值当做exit的参数。