Linux 进程(八) 进程的退出码

发布时间:2024年01月04日

? ? ? ? main 函数的返回值叫做进程的退出码。当进程成功退出的时候,我们一般用0来表示。进程失败的时候一般用非零来表示。我们使用不同的数字来表示进程退出时不同的失败原因。

????????我们查看系统的有多少退出码以及其含义时需要用到strerror()? 他的头文件和用法如下。

????????通过一下代码来查看系统有多少退出码

#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
int main()
{


  int i = 0;
  for(i;i<200;i++)
  {
    printf("%d:,%s\n",i,strerror(i));

  }
  return 0;
}

? ? ? ? 我们可以看到系统大概有134个退出码,每个退出码都有其自己的含义。由于太长只列举出来前几个。

?????????echo $?? 查看最近一个进程的退出状态,查看到的是0 表示的就是成功。

? ? ? ? 同时我们还可以自己设置进程退出码以及它的含义。

enum{
  success=0,
  open_err,
  malloc_err
};

const char* errorTodesc(int code)
{
  switch(code)
  {
    case success:
      return "sucesss";
    case open_err:
      return "open_fail";
    case malloc_err:
      return "malloc_fail";
    dafault:
      return "unknow error";

  }

}

int main()
{
  int code = malloc_err;
  printf("%s\n",errorTodesc(code));
  return malloc_err;
}

? ? ? ?除了进程退出,还有函数退出。?main函数退出表示进程结束,而函数退出仅仅表示函数调用完毕。函数也是有返回值的。调用函数一般我们通常想看到两种结果,第一函数执行结果 成功,或者失败。第二函数的执行情况,如打开一个文件,如果成功会返回一个文件指针,如果失败就会返回NULL。如:

????????打印出错误码,并且打印出错误原因。?

? ? ? ? 通过以上我们列举的情况可以说明进程退出有三种情况

? ? ? ? 1.程序执行完,结果是正确的。

? ? ? ? 2.程序执行完,结果是错误的。

? ? ? ? 3.程序执行完,程序就出现错误,结果无意义!!!

? ? ? ? 综上所述,只有当程序执行完的时候,结果才有意义。

? ? ? ? 进程出现退出是进程收到了异常的信号,每个信号都有不同的编号,每个编号都有自己的异常原因。

? ? ? ? 我们可以通过kill -l 查看有哪些信号:

? ? ? ? 我们这次主要了解 8 号 和 11号信号,8号信号相当与代码除0?,而十一号信号相当于对野指针进行解引用。

exit:

? ? ? ? exit是终止进程 其中status:是进程退出时候的退出码。

? ? ? ? 代码演示:

? ? ? ?该进程只跑1秒就退出。

????????并且退出码显示为3。

? ? ? ? 同时,如果在while循环中调用一个函数,并且调用exit() 那么进程也会同样退出的。如下:

????????

????????说明exit 是终止整个进程,在任意地方调用都是终止进程。

_exit 与 exit

????????

????????他们两个的功能是一模一样的,exit是c语言给我们提供的接口,而_exit是linux系统给我们提供的接口,那么二者有什么区别呢?

? ? ? ? 看代码:

? ? ? ? 程序停止了3秒然后hello linux ,hello gm 才被打印到屏幕上。

????????_exit 并没有把hello linux ,hello gm 打印到屏幕上,

????????这是因为_exit 没有刷新缓冲去,而exit刷新了缓冲区,这也是他们的区别。

那么exit 和_exit 是什么关系呢。

? ? ? ? exit 和 _exit 都是终止进程的,在整个系统中只有操作系统能够有权限来终止进程。

? ? ? ? 而_exit是系统调用接口,exit是c语言提供的库函数,库函数是不能终止进程的,只有操作系统提供的系统调用才能够终止进程,那么他们的关系就比较明确了。

? ? ? ? 就是exit在底层封装了_exit ,同时exit 中又添加了刷新缓冲区的功能。

? ? ? ? 为什么语言层面要进行封装呢?

? ? ? ? 第一:提高了语言的跨平台性。window系统,和Linux系统给我们提供的退出进程的接口肯定是不一样的(比如:函数名,函数参数,函数返回值)。所以Linux下的退出进程函数,在Windo ws下注定是跑不了的,造成代码的可移植性较差。所以c语言把系统调用接口在底层进行封装,在上层直接给一个exit函数。在Linux下使用Linux系统的调用接口给exit,在windows下使用windo ws的系统调用接口给exit,这样做在底层屏蔽了系统之间的差异,提高了可移植性、跨平台性。比如Java的虚拟机,python的命令行解释器,c/c++的库,都是为了解决跨平台而提出的解决方案。他们都会提供exit的功能,底层也封装了不同系统的系统调用接口。

? ? ? ? 第二:提高代码的可读性,降低程序员使用的门槛。

文章来源:https://blog.csdn.net/kqs__/article/details/135161787
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。