Linux相关概念和易错知识点(14)(进程终止、进程退出、退出信息)

news2024/11/24 20:23:09

1.进程终止

(1)错误码

对于程序常见错误信息,C/C++提供了信息解释,保存在<string.h>,使用strerror(错误码)就可以查询

错误信息成立的前提是错误码要和错误信息匹配,我们需要结合C/C++给我们的错误码来配套使用。<errno.h>被引用后程序就多了一个全局变量errno,当某一步操作出现问题时,errno会更新,此时我们就可以打印错误获取具体信息了。我们当然可以手动验证errno的存在以及它的作用。唯一需要注意的是要及时使用,因为如果有两个错误,errno很有可能会被后面的错误码覆盖。

我们可以简单使用一下,当打开不存在的文件时,错误码就会更新。

归根到底,这些错误码的更新主要还是靠库函数自己的支持,是在库函数里遇上错误后使用errno = (错误码)的方式来更新的,如果遇上不支持C/C++错误码的函数,我们就要自定义错误信息了。

(2)区分退出码和错误码

错误码反映程序运行中的某一行代码触发的错误,并且多个错误可以覆盖;而退出码是指我们程序里return跟的数字,代表整个程序的运行状态,在不同状况下通常唯一。

main函数的返回值是返回给父进程的。echo $?指令会显示最近一个程序退出时的退出码,它能反应程序是为何退出的。一般来说,退出码0表示程序执行成功,非0表示失败。当代码执行到我们在main最后写的return语句时,程序至少走到了我们规定的结尾,一切结果也都是在我们可控的范围,所以默认都写0。当然我们可以自己约定一套规则来表明不同状态。

注意echo $?要及时,如果运行多个程序,可能就会出现退出码的覆盖情况,这和错误码是一致的。但错误码是一个程序内部的多个错误信息覆盖,退出码是不同程序最终运行状态的覆盖,对象不一致。同时错误码和退出码之间没有必然联系,我们要分清。

退出码是给父进程看的,父进程一看就知道子进程任务完成的情况了。

(3)exit和_exit

函数的return代表返回上一层函数栈帧,返回值被上一层函数接收,对于main来说return的值才是退出码。还有两个函数,exit(1)和_exit(1)可以退出程序并返回值作为退出码,在代码任何地方都可以直接终止进程。但这两个函数有一点不同。

exit()会主动刷新缓冲区,将缓冲区的内容输出,但显然_exit()就不会,缓冲区里面的数据直接丢失。

这里也可验证当父进程先结束时,子进程会变成孤儿进程,交给系统保管,此时子进程也会变成后台进程,不会影响前台操作。

由于子进程变成孤儿进程,被系统带走了,因此bash不再是孤儿进程的父进程,bash得到的退出码也就只有父进程的退出码2。

_exit(1)偏向于系统层面,系统级别的头文件只能写<unistd.h>。exit()是语言级别的函数。语言级别的头文件可以写<cstdio><cstdlib>等。

我们需要知道,_exit()之所以被称为系统级函数,是因为_exit()就是操作系统的系统调用接口之一。我们的glibc等库是在系统调用接口之上,exit()是在_exit()的基础上加入了刷新缓冲区的功能。从这里我们就能发现,缓冲区这个概念在系统层面是不存在的,它是语言级别的。C和C++的缓冲区独立,分别适配各自语言的特性。

使用man 2 _wait可以查到系统级函数_wait(man手册第2页查系统级函数)

使用man 3 wait可以查到语言级函数wait(man手册第3页查语言级函数)

2.进程等待

(1)孤儿进程和僵尸进程

我们之前讲过当父进程退出而子进程还在工作时,子进程就会变成孤儿进程并被系统领养,孤儿进程会被自动移到后台运行。那么如何避免孤儿进程的产生呢?那就需要让父进程等一下子进程了。我们已经知道,如果什么都不做,父进程在执行完自己的任务后是会直接退出的,它是不会管子进程的。所以我们需要函数来阻挡它退出,那就是wait。

如果子进程完成后,其数据代码都会被释放,即进程地址空间里面堆区、栈区等对应的物理内存会被回收。但是最后还是会留下PCB的一些信息,以提供给父进程。父进程不会主动去读,当父进程结束退出后,子进程就变成了僵尸进程。我们依然需要父进程显式调用wait来读取子进程的信息。

注意,如果这个父进程是系统相关的进程,我们就无需担心,它会自己wait,但我们自己造的父子进程就要注意以上问题。

(2)wait

wait是语言级函数,我们可以查到它的相关参数,注意头文件的包含

我们使用wait(NULL)就可以等待任何进程,但注意每次wait都只能等待和读取一个进程,因此如果存在多进程情况,我们要保证wait的次数足够多。我们可以结合wait的返回值进行判断,当返回值是-1时就说明wait失败,该父进程下已经没有子进程了。

无论子进程跑得有多快,它最后都会变成僵尸等着父进程来回收,且按照上面的代码逻辑,只有wait到了一个子进程之后才会又fork,也就是说无论进程调度的公平性怎么样,无论子进程被调度得有多频繁,都会是上图结果,一父一子交替打印,导致这种结果和父进程被阻塞有很强关系。

父进程wait子进程除了避免僵尸或孤儿,还想要知道子进程任务完成的怎么样,也就是子进程的退出码。我们需要自己开辟一个int status,再将指针传过去,这样wait就可以通过指针修改传递子进程的退出码,同时返回子进程的pid给父进程

我们通过status可以得到退出相关信息,但是上图所示似乎不太对劲,每一次打印都是得到6144,而进程的退出码应该都是24才对。事实上,如果在status里只存退出码那就过于浪费了,在32bit里面仅有8bit用于存储退出码。

(3)进程退出信息

在wait返回的退出信息中,status除了退出码,还保存了一些其它信息。

①正常退出

正常退出是指程序通过我们自己写的return语句退出的,相当于程序整体在我们手上是可控的。我们可以根据退出码诊断程序的问题。

在退出信息status的32bit中,使用了低16bit,退出码的范围是0 ~ 255,刚好一字节。

②异常退出

异常退出是指程序根本就没有走到return我们写的语句就退出了,是被系统强制杀掉的。这种情况我们需要进一步得到进程的终止信息,就要用到前8位。

注意,异常退出后退出码的内容没有意义,根本就没走到我们的return语句,何来退出码?

终止信号是什么?是当出现很严重的问题时,系统会强制终止我们进程使用的信号。(如野指针(segmentation fault),0做除数(float point exception)等都会触发进程终止)当进程收到对应的信号,就会做出反应并修改自己的退出信息。这种信号和我们kill使用的选项一致

我们的kill -9之所以能杀掉进程,也是因为这条指令是向进程发送了9这个终止信号,这才让进程停下来。我们也能发现,kill没有0选项,这是因为终止信号不能为0,为0的话那就是程序正常退出。

还有一个就是core dump标志。当发生进程异常终止时,有可能会生成一个core dump文件,用于记录终止时进程调用的相关信息。如果有这个文件生成,那就是1,如果异常终止但没有生成文件或程序正常退出,那就是0.

③获取进程退出信息

使用位运算我们可以解读进程退出信息,我们只需要在自己需要的范围按位与1即可

每一个16进制都可以转为4bit,我们可以灵活控制16进制来控制这4bit中哪些是0,哪些是1,进而通过与运算将我们需要的信息拿到。

当然也有一些宏函数可以参考,不过只要我们记住了结构,获取到信息还是很容易的。

WIFEXITED(status):检查子进程是否正常退出
WEXITSTATUS(status):如果正常退出,获取子进程的退出状态码
WIFSIGNALED(status):检查子进程是被终止信号控制终止
WTERMSIG(status):获取导致子进程终止的终止信号
WCOREDUMP(status):检查子进程是否生成了 core dump 文件

(4)waitpid

我们刚刚的man 3 wait还显示了一个函数,waitpid,这是一个功能更强大的wait,为我们在读取子进程信息上留出了更多选择。

wait的出现已经能够消灭僵尸进程和控制孤儿进程了,并且也能得到退出信息。但我们其实有的时候不想让父进程一直被阻塞,这会降低程序的效率;并且有的时候我们想要创造孤儿进程,不想让父进程一直等着一个相当长时间不会退出的子进程,所以我们需要选择我们想要wait的进程。

waitpid的第一个参数是pid_t  pid,表示选择wait的子进程的pid,当pid是-1时表示不受限制,等待任意子进程,和wait功能一致;waitpid的第二个参数int*  status和wait一致,都是接收退出信息的指针。

waitpid的第三个参数int options是决定waitpid受不受阻塞的问题。受阻塞时options为0;当机器被阻塞时,一般叫做hang住了。当第三个参数是WNOHANG时,就说明waitpid采用非阻塞等待。非阻塞等待的意思是只在调用waitpid时去读取相应进程的退出信息,如果读到了就返回该子进程的pid,如果这个进程还没有退出就返回0,如果没有子进程了就返回-1

这就意味着wait或者options为0的waitpid会一直等进程把事情办完,而WNOHANG的waitpid看一眼进程就走了。我们可以减少wait的时间,但相应wait的次数就会增加,因为看一眼可能进程还没有退出,那就一定要多来看几眼直到进程全部退出,只不过这中间的时间进程可以干其他事,不会被阻塞而已。它和wait的本质功能没有差异。

我们能看到在子进程运行期间父进程还做了很多事情。注意waitpid一定要做到多次定期调用,防止僵尸进程出现

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

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

相关文章

股市入门常见术语介绍

鉴于最近行情讨论火热&#xff0c;我也想借此平台&#xff0c;结合我大学时期身边同学老师的投资经历&#xff0c;写一篇交易入门术语简介。内容不多但是足以达到科普之用。​ 希望大家能谨慎对待投资&#xff0c;始终保持谦虚学习的态度。不要迷失在瞬息万变的金融市场&#x…

第十九节 图像的缩放与插值

图像插值 最常见的四种插值算法 INTER_NEARRST0 INTER_LINEAR1 INTER_CUBIC2 INTER_LANCZOS44 相关应用场景 几何变换&#xff0c;透视变换&#xff0c;插值计算新像素resize&#xff0c; 如果size有值&#xff0c;使用size做缩放插值&#xff0c;否则根据fx与fy卷积。…

HUAWEI_HCIA_实验指南_Lib2.2_理解ARP及Proxy ARP

1、原理概述 ARP(Address Resolution Protocol)是用来将IP地址解析为MAC地址的协议。ARP表项可以分为动态和静态两种类型。动态ARP是利用ARP广播报文&#xff0c;动态执行并自动进行IP地址到以太网MAC地址的解析&#xff0c;无需网络管理员手工处理。静态ARP是建立I…

基于JAVA+SpringBoot+Vue的实习管理系统

基于JAVASpringBootVue的实习管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈喽兄…

<Project-6 pdf2tx> Python Flask 应用:图片PDF图书的中文翻译解决方案

重要更新&#xff01; Modified on 8oct24. P6已经被 P8 替代&#xff0c;后着支持多任务&#xff0c;多翻译机。在速度与资源占用上&#xff0c;都好于这个P6。 新的 P8 文章链接&#xff1a; &#xff1c;Project-8 pdf2tx-MM&#xff1e; Python Flask应用&#xff1a;在…

59 mysql 存储引擎之 PERFORMANCE_SCHEMA

前言 我们这里来看一下 performance_schema 存储引擎, 我们常见的那些 general_log, slow_log什么的, 都是基于 performance_schema 它主要是 使用 ha_perfschema 下面 api 来操作 performance_schema 中的信息 我们这里基于 performance_schema.variables_by_thread 这张基…

RGB转HDMI方案、MS7210驱动——FPGA学习笔记20

一、简介 见HDMI彩条显示——FPGA学习笔记12-CSDN博客 二、TMDS编码原理 HDMI 采用 TMDS (Time Minimized Differential Signal) 最小化传输差分信号传输技术&#xff0c; 是美国 Silicon Image 公司开发的一项高速数据传输技术&#xff0c; 将视频、 音频、 控制信号进行编码…

电脑上下载配置Flutter Sdk及如何配置Flutter国内镜像

电脑上面下载配置 Flutter Sdk &#xff08;所有版本方法一 样&#xff09;&#xff1a; 1 、下载 Flutter SDK https://flutter.dev/docs/development/tools/sdk/releases#windows 2 、把下载好的 Flutter SDK 随便减压到你想安装 Sdk 的目录 如减压到 &#xff08; F:\flu…

Flink job的提交流程

在Flink中&#xff0c;作业&#xff08;Job&#xff09;的提交流程是一个复杂的过程&#xff0c;涉及多个组件和模块&#xff0c;包括作业的编译、优化、序列化、任务分发、任务调度、资源分配等。Flink通过分布式架构来管理作业的生命周期&#xff0c;确保作业在不同节点上以高…

【Java】多线程代码案例

多线程代码案例 单例模式初步了解饿汉模式懒汉模式线程安全问题分析存在的问题 生产者消费者模型初识生产者消费者模型初识阻塞队列生产者消费者模型的意义BlockingQueue阻塞队列模拟实现 定时器初识计时器初识Timer类初识 schedule() 方法简易定时器的实现思路讲解代码书写 线…

面试字节跳动精选20道产品经理面试题分析回答

分享20道字节跳动产品经理的面试题&#xff0c;产品经理的面试很多会跟项目强关联&#xff0c;比如面试电商产品经理&#xff0c;就要多聊电商的业务&#xff0c;所以我们选了一些比较通用的&#xff0c;面试题及我们的分析回答。 01 20道面试题&#xff08;前10道&#xff0…

react中的重定向Redirect

1, 首先引入 import {BrowserRouter,Route,Switch,Redirect} from react-router-dom 2,使用 一般写在所有路由注册的最下方&#xff0c;当所有路由都无法匹配时&#xff0c;跳转到Redirect指定的路由 <Switch><Route path"/about" component{About}/>…

探索SLMi823x系列 40V, 1A/4A 具有不同配置 双通道死区可编程 隔离驱动器

SLMi823x系列选型型号&#xff1a; SLMi8230BDCG-DG SLMi8230DDCG-DG SLMi8231BDCG-DG SLMi8231DDCG-DG SLMi8232BDCG-DG SLMi8232DDCG-DG SLMi8233BDCG-DG SLMi8233DDCG-DG SLMi8234BDCG-DG SLMi8234DDCG-DG …

codeforces- 973-div2----补题

1、求最小时间 思路&#xff1a;简单的模拟 木桶效应 #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int dx[] { 0,1,0,-1 }; int dy[] { 1,0,-1,0 }; const ll N 2e5 5; const ll mod 1e9 7; ll a[N]; void solve…

液相/气象色谱仪原理

色谱仪 1.液相色谱 常用的是柱色谱 高效液相色谱 在 HPLC 系统中&#xff0c;** 色谱柱内的固定相通常是由颗粒很细的填充物组成。这些细小的填充物具有更大的比表面积&#xff0c;能够提供更多的与样品分子相互作用的机会&#xff0c;从而提高分离效率和分辨率 **。然而&am…

双十一买什么东西好?五大双11好物推荐分享!

双十一购物节即将来临&#xff0c;作为一年一度的购物盛事&#xff0c;许多人都在考虑如何挑选心仪的商品。在这个特殊的日子里&#xff0c;各大电商平台纷纷推出了令人心动的优惠活动&#xff0c;琳琅满目的商品让人眼花缭乱。无论是为自己添置新物品&#xff0c;还是提前采购…

E系列I/O模块在锂电装备制造系统的应用

为了满足电池生产线对稳定性和生产效率的严苛要求&#xff0c;ZLG致远电子推出高速I/O应用方案&#xff0c;它不仅稳定可靠&#xff0c;而且速度快&#xff0c;能够迅速响应生产需求。 锂电池的生产工艺较为复杂&#xff0c;大致分为三个主要阶段&#xff1a;极片制作、电芯制作…

若依 从字典类型跳到字典数据跳到了404

描述&#xff1a; 在字典类型从表中字典类型跳转到详情的字典数据时跳到了404 解决过程&#xff1a; 由于我的id统一是用GUID&#xff0c;所以想到了路由表相关路由的正则校验&#xff0c;若依是int类型&#xff0c;我直接删掉了&#xff0c;改了之后还是跳404 后面想是路由表…

利用编程思维做题之反转链表

牛客网题目 1. 理解问题 给到我们的是一个单链表的头节点 pHead&#xff0c;要求反转后&#xff0c;返回新链表的头节点。 首先在心里设想能够快速理解的例子&#xff0c;如给你123序列&#xff0c;要你反转此序列如何回答&#xff1f;将最后一个数字3作为头&#xff0c;然后修…

如何修复 Windows 10 /11上 CrowdStrike 导致的蓝屏死机问题

CrowdStrike 是一家领先的网络安全技术提供商&#xff0c;为终端、云工作负载、身份和数据提供安全服务。其 Falcon 平台是一种统一的、云交付的安全解决方案&#xff0c;旨在防止所有类型的攻击&#xff0c;包括恶意软件等。然而&#xff0c;Windows 上 Falcon Sensor 代理的最…