当前位置: 首页 > news >正文

【Linux手册】进程终止:进程退出和信号的响应机制

文章目录

  • 前言
  • 进程退出的场景
    • 退出码
    • errno
  • 代码异常终止
  • exit和_exit

前言

进程最终都会终止,进程终止本质上就是进程资源的释放,回收。本文侧重于进程终止的方式,以及自己编写代码时让进程终止的方法。

进程退出的场景

进程退出一共分为三种:

  • 进程运行完毕,结果正确。这是我们最希望的情况;
  • 进程运行完毕,结果不正确;
  • 进程异常结束。

退出码

进程运行结束就是main函数调用完毕了,可以根据main函数的返回值来判断进程运行的情况。一般情况下在main中return 0表示程序正常结束,不同的退出码可以代表不同的含义,这样就能将进程的运行结果返回出来了。

如何查看不同的退出码对应的信息???

在C语言中有char* strerror(int i) 函数可以查看不同的退出码的含义;
在这里插入图片描述

通过以上代码可以显示不同的返回值代表的含义,当然如果你觉得这些退出与信息的设定并不是自己希望的,你也可以自己设计一套错误表示,必定是我们自己在进行编码return值嘛。

进程的退出码最终应该被父进程拿到,因为父进程才是最关心当前进程的"人"。我们知道在命令行上创建的所有进程都是bash的子进程。可以通过echo $? 的方式来获刚刚运行的子进程退出码。
在这里插入图片描述

根据上图可以看到我故意将程序的退出码设置为11,通过echo $?也确实看到了上一个进程的退出码是11.

但是如果再次使用echo $?就会发现,退出码变成了0,这是为什么???

退出码变成了0说明这个退出码就不是./test.eve的退出码,那它肯定就是echo的退出码,每一条指令都是一个可执行程序,那指令有退出码也很正常。

当使用fork创建子进程的时候,父进程又如何获取到子进程的退出码呢???

父进程需要通过进程等待的方式来获取子进程的退出码以及相关信息,关于进程等待相关知识后面会专门开一个专题讲解

errno

在调用一些库函数的时候,有可能会出现库函数调用失败的情况,errno会存储最近一次库函数调用失败的返回码。

比如下面调用malloc如果开辟空间失败,可以将errno存储到ret中进行返回,来告诉父进程malloc开辟空间失败。
在这里插入图片描述

因为errno存储的是最近一次库函数调用时出错的返回码,如果一个程序中又多个位置库函数调用失败,就会导致错误码被覆盖,所以要及时对errno中的值进行检查。

代码异常终止

代码异常终止的情况在日常编码中也是很常见的,比如除0操作,数组越界…

对于异常终止的程序退出码是没有意义的 ,异常终止可能代码根本没有跑完,就算是运行完了,其退出码也可能因为异常情况而发生改变。

因为异常终止的情况所以当一个进程结束时,先看代码是否异常,再看退出码
在Linux中可以通过 kill -l 的方式查看各种异常信息,当然这些信号都是一些缩写。
在这里插入图片描述

当程序出现异常的时候,异常会转化为信号的方式发送给进程,从而让进程直接退出。 当然我们也可以在bash命令行上对进程发送信号,其中我们比较熟的有:kill -9 PID杀死一个进程,kill -19 PID将进程暂停。

exit和_exit

void exit(int state)在我们编写代码中比较常见,就是直接将进程终止,并返回退出码。

exit在任意一个位置调用,进程都会直接终止,不会再执行后面代码了。

void _exit(int state) 是一个系统调用接口,那它与exit有什么区别呢?通过以下两段代码看看。

在这里插入图片描述

在这里插入图片描述

在使用exit()的程序中打印出来"hello Linux",而使用的_exit()中并没有打印出任何东西,通过这个现象说明两者确实是不一样的。

在上面代码打印中没有使用\n或者其他刷新缓冲区的操作,程序就直接退出了。而两个接口不同之处就在于是否打印出信息。
所以exit()和_exit()的主要区别在于是否会刷新缓冲区 很显然_exit()没有刷新缓冲区,exit()刷新了缓冲区。

_exit()是系统调用接口,是操作系统提供的一个接口,而exit()是库函数,是程序员对系统调用接口进行封装后提供给我们的接口。实际上exit()中调用了_exit()接口,只不过在调用该接口之前对缓冲区进行了刷新。
在这里插入图片描述

通过exit()和_exit()调用的区别也可以猜测,缓冲区一定不在内存中的操作系统内核区域,而是在用户区,因为操作系统不会做浪费空间和资源的行为,如果缓存在操作系统中一定会进行刷新,如果不刷新操作系统不就浪费空间了嘛。

http://www.lqws.cn/news/548065.html

相关文章:

  • 微软全新开源的Agentic Web网络项目:NLWeb详解
  • 【C/C++】单元测试实战:Stub与Mock框架解析
  • 【世纪龙科技】吉利博瑞汽车车身诊断与校正仿真教学软件
  • window显示驱动开发—DirectX 图形内核子系统(二)
  • Ai大模型 - ocr图像识别形成结构化数据(pp-ocr+nlp结合) 以及训练微调实现方案(初稿)
  • 第六章 总线
  • 四大高频设计题深度解析:【LRU缓存】、【LFU缓存】、最大频率栈、餐盘栈
  • 论面向服务的架构设计
  • Java项目:基于SSM框架实现的宠物综合服务平台管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告】
  • MySQL在C中常用的API接口
  • 楼宇自控系统以智能化管控,全方位满足建筑节约、安全与可靠运行需求
  • 嵌入式项目:基于QT与Hi3861的物联网智能大棚集成控制系统
  • 模型部署和推理架构学习笔记
  • <script setup> 语法糖
  • 中高端服装品牌开展全渠道零售业务,如何选OMS订单管理系统?|商派
  • 成都芯谷金融中心·文化科技产业园:绘就区域腾飞新篇章
  • 【Pandas】pandas DataFrame resample
  • 疲劳检测与行为分析:工厂智能化实践
  • 解剖智能运维三基石:Metrics/Logs/Traces
  • 广东广电U点-创维E900-S-海思MV310芯片-海兔线刷烧录固件包
  • 香港 8C 站群服务器买来可以做哪些业务?
  • TCP/IP协议简要概述
  • linux初阶---一些指令
  • day49-硬件学习之I2C(续)
  • Tomcat Maven 插件
  • 第六章 STM32内存管理
  • 黑马JVM解析笔记(五):深入理解Java字节码执行机制
  • SpringBoot自动配置原理详解
  • 修复opensuse 风滚草rabbitmq的Error: :plugins_dir_does_not_exist问题
  • 关于前端npm install安装依赖和打包的一些问题记录