文章目录

  • 1 进程的退出


1 进程的退出

在Linux系统中,进程终止(或者称为进程退出,为了统一,下文均使用”终止”一词)的常见方式有5种,可以分为正常终止与异常终止:

正常终止:

  • 从main函数返回。
  • 调用exit()函数终止。
  • 调用_exit()函数终止。

异常终止:

  • 调用abort()函数异常终止。
  • 由系统信号终止。

在Linux系统中,exit()函数定义在stdlib.h中,而_exit()定义在unistd.h中,exit()和_exit()函数都是用来终止进程的,当程序执行到exit()或_exit()函数时,进程会无条件地停止剩下的所有操作,清除包括 PCB在内的各种数据结构,并终止当前进程的运行。不过这两个函数还是有区别的。

如何进入退出后的容器 退出进程_异常终止

从图中可以看出,_exit()函数的作用最为简单:直接通过系统调用使进程终止运行,当然,在终止进程的时候会清除这个进程使用的内存空间,并销毁它在内核中的各种数据结构;而exit()函数则在这些基础上做了一些包装,在执行退出之前加了若干道工序:比如exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,这就是”清除I/O缓冲”。

由于在 Linux 的标准函数库中,有一种被称作”缓冲 I/O(buffered I/O)”操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续读出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区中读取;同样,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(如达到一定数量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度,但也为编程带来了一些麻烦。比如有些数据,认为已经被写入文件中,实际上因为没有满足特定的条件,它们还只是被保存在缓冲区内,这时用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失。因此,若想保证数据的完整性,就一定要使用 exit()函数。

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

下面一起看看_exit()与exit()函数的使用方法:

头文件:

#include <unistd.h>
#include <stdlib.h>

函数原型:

void _exit(int status);
void exit(int status);

这两个函数都会传入一个参数status,这个参数表示的是进程终止时的状态码,0表示正常终止,其他非0值表示异常终止,一般都可以使用-1或者1表示,标准C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,表示正常与异常终止。


参考资料:

  1. [野火]i.MX Linux开发实战指南