【Linux】进程终止与进程等待

目录

进程终止

errno

exit和_exit

进程等待

wait和waitpid

宏:WIFEXITED

非阻塞等待


进程终止

下面要谈的一个话题就是进程终止,就是说一个进程退出了,可能有三种情况

1.进程代码执行完,结果是正确的

2.进程代码执行完,结果是错误的

3.进程代码没有执行完,进程出异常了,中途退出了

其实我们写的main函数执行起来就是一个进程,而我们一般写的return 0,就叫做进程的退出码。一般0表示正确执行,第一种情况;而非0表示执行失败,第二种情况。因为main函数的return 0就已经是代码的最后部分了。

为什么用非0表示执行失败呢?因为成功就是成功了,而失败可能会有很多种原因。进程的退出码是给机器看的,要是给人看,就要把退出码转化成错误描述,这个错误描述可以是系统或语言自带的,也可以自定义,下面我们先用strerror函数看一下系统中的错误描述

我们可以看到有很多错误描述,到133个了

这时我们就能解释我们瞎给比如ls 后面一个选项,bash进程,就是命令行解释器报的错是什么了,比如:

这不就是上面的二号错误吗,另外,下面的指令可以查看最近一次进程的退出码

为什么第二次用显示0呢?因为echo $?也是一个进程它是成功执行的

我们上面说也可以自定义,那就可以创建几个字符串枚举值,并且枚举值是可以表示整数的,这样就可以自己去定义错误码了,比如:

上面我们说了前两种情况,第三种情况是进程没有执行完,中途出现异常了,只要中间出现异常,其实结果对与否就没有意义了。其实中途出现异常本质上就是进程收到了异常信号,就是kill -l那一系列的信号

比如:

8号信号对应的是 SIGFPE(Floating-Point Exception)信号。这个信号用于指示浮点运算异常,比如除以零或溢出等情况。

11号信号对应的是 SIGSEGV(Segmentation Fault)信号。这个信号用于指示进程发生了内存段错误,即试图访问无效的内存地址。

并且有一个细节就是这些错误是从1开始的,这跟我们下面的如何用16比特位表示退出码和收到什么信号是有关系的,并且这些大写的字母都是宏定义

所以进程执行的情况可以由两个数字表示,一个是收到什么信号(0就表示没有收到信号),一个是退出码。

errno

除了进程退出,就是main函数退出,我们还有普通函数退出,那我们如何知道它的运行情况呢?我们也有个存放错误码的东西,叫errno,就是说,函数如果执行失败的话,那么错误码会放在erron这个整形变量里,这个一般库函数才会有这个错误码,因为库函数内部一般是有这个赋值的,我们一般写的函数没有,比如fopen,可以看一下它的返回值

可以看到errno这个东西,下面写一个代码看一下

其实我当前目录根本就没有这个文件,并且是以只读的方式打开文件,所以它肯定会出错,错误信息就存在errno里面,我们也可以看具体字符信息,运行之后就是这样

exit和_exit

我们如果想让一个进程退出可以用exit或_exit前者是库函数,后者是系统调用,我们可以来查一下

这里的参数status就是你想让进程退出时的退出码,我们通过一段代码来展示一下它们的区别

我们写这样一个代码,运行完后发现什么都不打印,而把_exit改成exit后就会打印,这就说明exit会刷新缓冲区其实exit就是封装了_exit,为什么要这样做呢?

其实我们知道库函数和系统调用是上下层关系,不同的操作系统的系统调用是不同的,比如Windows下_exit就用不了,所以这时我们把系统调用再封装一层成为库函数,不同的操作系统封装不同的系统调用,但是它们的库函数的接口就是一样的了,这就通过库函数屏蔽掉了系统调用的差异,就实现了语言的可移植性和跨平台性,所以不同的操作系统就会安装不同的库文件。并且这里的缓冲区是库级别的缓冲区,所以系统调用是无法刷新的,如果是操作系统级别的,那就会刷新,因为操作系统不会让它白白占着空间的。

进程等待

我们之前说过,父进程要回收子进程的PCB来拿到子进程的退出信息,如果父进程不管不顾,子进程就会进入僵尸状态,就会造成内存泄漏,这时就算kill -9也无能为力,因为谁也不能杀死一个已经死掉的进程。而父进程回收子进程就是通过进程等待

wait和waitpid

我们有两种等待方式,分别是wait和waitpid,我们可以man查一下

这里的status是一个输出型参数,通过给一个整型变量的地址,这个函数内部就可以将退出信息写入到这个地址中,如果不想让它写入可以给NULL;pid就是要等待的子进程的pid,如果是-1的话,那么等待任一子进程,这时与wait等效options是确定父进程是阻塞等待还是非阻塞等待

我们再看一下返回值是什么意思

就是说:如果成功等待到了子进程结束,就返回子进程的PID;如果等待失败(如果pid参数指定的子进程不存在或不是当前进程的子进程或是如果调用被一个信号中断)就返回-1;如果非阻塞等待(WNOHANG)等待后,子进程状态没变,那么返回0。

知道了各个参数和返回值是什么意思,那我们就可以简单的来使用一下wait和waitpid:

我们上面说过,任何进程最终的执行情况可以有两个数字表明,一个是退出码,一个是退出信号,如果收到退出信号,那么最终的退出码没有意义waitpid就是通过status这个输出型参数拿到这两个数字的,那么这两个数字是怎么存在一个status中的呢?我们来看一下:

我们只用status中32个比特位中的低16位,也就是0-15位,如果进程没有收到退出信号,那么8-15位就表示子进程的退出码,所以我上面获取退出码时是先进行位右移8位,然后按位与上0xff;如果收到退出信号,那么0-6位表示收到什么退出信号,第七位表示core dump标志,这个标志先不用管,所以我上面是直接按位与上0x7f。

为了验证,我们也可以故意给一个错误的代码,比如访问空指针,这时让程序运行,看看父进程能否分析出子进程的退出信号

我们可以看到,父进程确实等待到了子进程的退出信号11

宏:WIFEXITED

其实不一定非得像上面那样进行位操作才可以得到退出码,我们还可以通过宏来得到退出码或退出信号,像下面这样

wait if exited这个表示如果进程是正常终止,就是没有收到退出信号,那就返回真,所以我们用wait exit status来获取退出码;如果为假,我们用wait terminate signal来获取退出信号。因为只要有退出信号,退出码就没意义,退出码有意义时没有退出信号,所以它们两个只要根据不同情况获取一个即可。

非阻塞等待

我们上面说过waitpid的第三个参数如果是0,那么就是阻塞等待如果是WNOHANG,就是非阻塞等待,什么是阻塞等待呢?其实就是父进程在等待子进程退出时如果什么都不做,就叫做阻塞等待如果父进程使用WNOHANG后waitpid后就会立即返回,不管是否有子进程退出,如果等到了子进程退出,返回值就是子进程的pid,如果没有等到就返回0。因为waitpid只会运行一回,有可能等不到子进程,所以一般把它放进一个循环中,并且父进程执行完waitpid后还可以执行自己的工作,我们一般可以这样去实现

进程结束之后只留下进程PCB,所以父进程肯定是通过子进程的PCB获取退出码和退出信号的,我们在Linux源码中也确实可以看到

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/640802.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kali下载zsteg和stegpy

1.kali下载zsteg 从 GitHub 上克隆zsteg到kali git clone https://github.com/zed-0xff/zsteg 切换目录 cd zsteg 用于安装名为 zsteg 的 Ruby Gem 包 gem install zsteg 2.kali下载stegpy 下载网站内的stegpy-master压缩包GitCode - 开发者的代码家园 并拉到kali中 切换到s…

pycharm配置python开发环境—miniconda+black+gitlab

下载miniconda管理python开发环境 miniconda下载地址:https://docs.anaconda.com/free/miniconda/ miniconda最新版本的python版本是python3.12.2,下载这个miniconda最新版本后,会导致执行conda create -n py31013 python3.10.13指令配置py…

Excel中sum的跨表求和

#实际工作中,一个xlsx文件中会包含多个Excel表格,一般会有“总-分”的关系,如何把分表里的数字汇总到总表里呢? 一般有上图所示的两种表达方式。 可以使用通配符 *:代表任意个数、任意字符; ?&…

成都爱尔眼科医院《中、欧国际近视手术大数据白皮书2.0》解读会圆满举行

2024年5月12日,爱尔眼科联合中国健康促进基金会健康传播与促进专项基金、新华社新媒体中心与中南大学爱尔眼科研究院、爱尔数字眼科研究所重磅发布《中、欧国际近视手术大数据白皮书2.0》。这是继2021、2022年在国内相继发布《国人近视手术白皮书》、《2022中、欧近…

Java进阶学习笔记7——权限修饰符

什么是权限修饰符? 就是用来限制类中的成员(成员变量、成员方法、构造器、代码块....)能够被访问的范围。 protected使用的比较少,但是程序员还是要阅读代码,看官方文档是怎么写的,都会接触到protected修饰…

计算机网络学习小结_物理层

数据通信基础知识 信道相关概念 单工,半双工,全双工 基带信号:信源发出的信号,如计算机输出的文字和图像都是基带信号。基带信号常包含较多低频成分,有的还有直流成分,有的信道不能传输低频成分和直流成…

手撕算法|斯坦福大学教授用60页PPT搞定了八大神经网络

人工智能领域深度学习的八大神经网络常见的是以下几种 1.卷积神经网络(CNN): 卷积神经网络是用于图像和空间数据处理的神经网络,通过卷积层和池化层来捕捉图像的局部特征,广泛应用于图像分类、物体检测等领域。 2.循…

2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(下):多智能体开发

传送门: 《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(上):MetaGPT安装、单智能体开发》《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(中)&…

对AI 感兴趣的小伙伴

如图,欢迎来玩儿! 欢迎来玩儿

区块链论文总结速读--CCF A会议 USENIX Security 2024 共7篇 附pdf下载

Conference:33rd USENIX Security Symposium CCF level:CCF A Categories:网络与信息安全 Year:2024 Num:7 1 Title: Practical Security Analysis of Zero-Knowledge Proof Circuits 零知识证明电路的实用安全…

js禁止使用浏览器的前进后退按钮的方法

效果图: // 替换当前页面的历史记录,使用户不能通过浏览器的前进后退按钮导航 history.replaceState(null, null, location.href);// 监听浏览器的历史记录变化事件 window.onpopstate function(event) {// 再次替换当前页面的历史记录,确保…

AWS安全性身份和合规性之Identity and Access Management(IAM)

通过AWS Identity and Access Management(IAM),您可以指定谁或什么能够访问AWS中的服务和资源、集中管理精细权限,并分析访问权限以优化跨AWS的权限。 比如一家软件开发公司需要在AWS上创建多个开发人员账户,并对其进…

解禁谷歌等浏览器禁止网站使用麦克等媒体设备

1、浏览器地址栏输入chrome://flags/ 微软的chromium内核的edge浏览器,既可以输入:chrome://flags/ ,也可以输入edge://flags/ 2、打开后,界面如下 3、输入搜索,unsafe,并启用、输入需要启用的网址

Algoriddim djay Pro Ai for Mac:AI引领,混音新篇章

当AI遇上音乐,会碰撞出怎样的火花?Algoriddim djay Pro Ai for Mac给出了答案。这款专业的DJ混音软件,以AI为引擎,引领我们进入混音的新篇章。 djay Pro Ai for Mac的智能混音功能,让每一位DJ都能感受到前所未有的创作…

SqlSession是什么?在MyBatis-Spring中有什么应用?

目录 一、SqlSession是什么 二、SqlSession在MyBatis中的应用 三、SqlSession在Spring中的应用 一、SqlSession是什么 SqlSession 是 MyBatis 框架中的一个核心概念,它代表与数据库的一次会话。MyBatis 是一个流行的 Java 持久层框架,用于简化数据库…

智能界面设计:数字孪生与大数据结合的美学典范

智能界面设计:数字孪生与大数据结合的美学典范 引言 在数字化浪潮的推动下,智能界面设计成为了连接用户与技术的重要桥梁。数字孪生技术与大数据的结合,不仅为UI设计带来了前所未有的创新机遇,更成为了美学与功能性融合的典范。…

项目9-网页聊天室8(消息的发送和接收之websocket)

这是整个项目最最核心的部分. 但是这个部分的编写,需要依赖"基础设施" 包括不限于前面已经实现的 主界面,用户管理,会话管理, 好友管理, 消息管理 等等.... 发送消息,和接收消息,需要"实时传输 张三 发了一条消息,李四 这边立即就能接收到, 这样的…

【设计模式】JAVA Design Patterns——Converter(转换器模式)

🔍目的 转换器模式的目的是提供相应类型之间双向转换的通用方法,允许进行干净的实现,而类型之间无需相互了解。此外,Converter模式引入了双向集合映射,从而将样板代码减少到最少 🔍解释 真实世界例子 在真实…

图论-最短路算法

1. Floyd算法 作用:用于求解多源最短路,可以求解出任意两点的最短路 利用动态规划只需三重循环即可(动态规划可以把问题求解分为多个阶段)定义dp[k][i][j]表示点i到点j的路径(除去起点终点)中最大编号不超…