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

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的功能,底层也封装了不同系统的系统调用接口。

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

相关推荐
2035去旅行10 小时前
bootcmd 详细讲解
linux·嵌入式·arm·soc
陈希12311 小时前
Linux 防火墙配置实战:firewalld、iptables 与云安全组
linux·运维·服务器
女神下凡12 小时前
芯参谋(95):嵌入式文件系统_开发指南
linux·服务器·arm开发·驱动开发·设计规范
且从容.15 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道16 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
且从容.19 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落20 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨20 小时前
WSL2的安装与使用
linux·wsl
微小的鱼20 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng21 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器