【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源码中也确实可以看到

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【活动】开源与闭源大模型:探索未来趋势的双轨道路

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 开源与闭源大模型:探索未来趋势的双轨道路引言一、开源大模型&#…

翻译《The Old New Thing》- The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag

The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071128-00/?p24353 Raymond Chen 2007年11月28日 FORMAT_MESSAGE_IGNORE_INSERTS 标志的重要性 简要 文章讨论了使用FormatMes…

评估企业的业务是否存在高风险的六个步骤

风险的幽灵使得组织别无选择,只能改善各种网络风险的总体管理。以下是一个基于信息安全论坛的IRAM2方法论的分步过程,网络安全和风险从业者可以利用它来评估和管理信息风险。 第1步:范围界定练习 范围界定练习的目标是提供一个以业务为中心…

基于springboot+vue的招聘信息管理系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

K8s的常用命令以及yaml文件的创建

目录 一、声明式管理方法:YAML文件 1、yaml文件简介 2、yaml和json的主要区别: 3、YAML的语法格式 4、yaml文件组成部分 ①控制器定义 5、查看api资源版本标签 6、编写nginx-deployment.yaml资源配置清单 6.1创建资源对象 6.2查看创建的pod资源…

Unity-Sprite Atlas+UGUI系统的运行原理

每日一句:别听世俗耳语,看自己的风景就好 目录 SA的原理: SA的优点: SA的缺点: DrawCall是什么? 批处理是什么? 我们先了解一下UGUI系统的运行原理吧! 提到图集优化&#xff0…

cocosCreator动态生成二维码

cocosCreator 版本:3.7.2 开发语言:typeScript 我们在游戏开发中,经常会生成一个专属于玩家个人的二维码,比如说推广、充值等功能。 接到这个任务,在网上找了下,还是有很多教程的。但是这些教程大部分都是用…

Ollydbg动态分析MessageBoxA输出hellow world

一、目的 找到main函数找到调用的MessageBoxA函数 测试源码 #include <iostream> #include <windows.h>int main() {MessageBoxA(NULL, "Hellow World", "Title", MB_OK);return 1; }二、快捷键 指令快捷键说明RestartCtrlF2重新开始调试S…

buu[HCTF 2018]WarmUp(代码审计)

buu[HCTF 2018]WarmUp&#xff08;代码审计&#xff09; 题目 访问source.php <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php…

电脑键盘如何练习盲打?

电脑键盘如何练习盲打&#xff1f;盲打很简单&#xff0c;跟着我做&#xff0c;今天教会你。 请看【图1】&#xff1a; 【图1】中&#xff0c;红色方框就是8个基准键位&#xff0c;打字时我们左右手的8个手指就是放在这8个基准键位上&#xff0c;F键和J键上各有一个小突起&…

Spring6基础笔记

Spring6 Log4j2 1、概述 1.1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发…

mysql图形化界面及将mysql注册成后台程序

安装图形化界面版本 右键新建数据库 字符集使用utf8防止以后数据库中存在中文字符导致乱码 将mysql注册成后台程序 cmd进入命令行界面 切换路径到cd /mysql/bin 将mysql注册成后台程序 mysqld.exe --install mysql1 (失败&#xff0c;说明没有权限) 以管理员身份打开成功…

SYSTEM文件夹介绍(sys文件夹、deley文件夹、USART 文件夹、SysTick、printf函数、fputc函数、半主机模式)

参考 http://t.csdnimg.cn/P9H6x 一、sys文件夹介绍 在上述介绍的 sys 文件夹中&#xff0c;涉及了一些与系统控制、中断管理、低功耗模式、栈顶地址设置、系统时钟初始化以及缓存配置等相关的函数。以下是对每个功能的简要分析&#xff1a; 1.中断类函数&#xff1a; sys_n…

CCF20230901——坐标变换(其一)

CCF20230901——坐标变换&#xff08;其一&#xff09; #include<bits/stdc.h> using namespace std; int main() {int n,m,x[101],y[101],x1[101],y1[101];cin>>n>>m;for(int i0;i<n;i)cin>>x1[i]>>y1[i];for(int j0;j<m;j)cin>>x[…

负反馈系统中运放的相位裕度仿真、环路增益的stb仿真

这里没目录标题 一、引言二、巴克豪森判据、最坏情况下的相位裕度、相位裕度三、相位裕度与开环&#xff0c;环路&#xff0c;闭环增益的关系四、环路增益、闭环增益和相位的仿真4.1 运放为双入单出时4.1.1 系统的闭环增益4.1.2 stb仿真系统的环路增益和相位裕度&#xff08;环…

Python项目:数据可视化_下载数据【笔记】

源自《Python编程&#xff1a;从入门到实践》 作者&#xff1a; Eric Matthes 02 下载数据 2.1 sitka_weather_07-2021_simple.csv from pathlib import Path import matplotlib.pyplot as plt import csv from datetime import datetimepath Path(D:\CH16\sitka_weather_0…

python web自动化(Allure报告)

Allure详细安装请看之前的博客 1.Allure配置与⼊⻔ 运⾏⽤例&#xff0c;⽣成allure报告 pip install allure-pytest -i https://mirrors.aliyun.com/pypi/simple/ 运⾏⽤例&#xff0c;⽣成allure报告 # main.py import os import pytest if __name__ __m…

ROS学习记录:用C++实现IMU航向锁定

前言 获取IMU数据的C节点 在了解了如何获取到IMU的姿态信息&#xff08;链接在上面&#xff09;后&#xff0c;接下来尝试实现让一个节点在订阅IMU数据的时候&#xff0c;还能发布运动控制指令&#xff0c;使机器人能对姿态变化做出反应&#xff0c;达到一个航向锁定的效果。 …

神奇动物在哪里,但导演是微软

大数据产业创新服务媒体 ——聚焦数据 改变商业 一说到计算机视觉&#xff0c;大多数人第一时间联想到的便是“人脸识别”、“自动驾驶“、道路检测”等跟我们日常生活息息相关的关键词。而在2024年的5月末&#xff0c;微软在GitHub上面上传了这样一个计算机视觉的项目&#x…

几个速度比较快的 Linux 开源镜像站及支持的资源列表

搜狐开源镜像站 https://mirrors.sohu.com/ File Name CPAN/ FreeBSD/ QpenBSD/ RockyL apache/ archlinux/ centos/ ceph/ cygwin/ debian/ debian–cd/ debian-security/ deepin/ deepin-cd/ docker-ce/ fedora/ fedora-epel/ gentoo/ lib/ mysql/ nginx/ opensuse/ php/ ubu…