Linux——进程终止/等待/替换

前言

  本章主要对进程终止,进程等待,进程替换的详细认识,根据实验去理解其中的原理,干货满满!

1.进程终止

概念:进程终止就是释放进程申请的内核数据结构和对应的代码和数据

进程退出的三种状态

  • 代码运行完毕 结果正确  
  • 代码运行完毕 结果错误
  • 代码中止异常

我们在学习C语言的时候,写main函数,一般都会写return 0;main函数的返回值,通常就代表程序的执行情况,0代表成功,非0代表代码运行完毕,结果错误,不同的值代表不同的错误

当父进程创建子进程是为了让子进程完成某种任务,当子进程结束,肯定要将执行结果返回给父进程,让父进程知道是什么情况,我们知道子进程结束会保留task_struct,等待父进程获取结果信息,此时子进程就是僵尸进程,执行结果,也就是返回值就会存放到task_struct中,被父进程获取

1.1退出码

进程结束返回的一个状态 通常是一个整数值 

echo $?

打印最近一个进程退出时的退出码

errno:当库函数调用失败或者系统调用失败 他们通常会将一个特定的错误代码赋值给errno

 strerror是C语言的一个库函数,该函数接收一个errno的错误代码作为参数, strerror负责将这些错误代码转换为具体的错误描述信息,一共有134条

我们可以看到0表示成功  1表示操作不被允许  2表示没有这个目录或文件 3表示没有这个进程

相信后面的大家也可以读懂  这样我们就可以根据退出码知道我们的错误是什么了

 

此时在当前目录并没有c.txt文件,ls是C语言写的一个程序,当执行完程序,发现文件不存在,此时的退出码是2,不就是上面的2号找不到文件吗 

1.2进程常见的退出方法

1.2.1从main返回

我们知道main函数是程序的入口,当main函数结束,也return了,进程也就结束了

其他的函数只表示调用函数完成了 返回退出码 并不代码进程结束

1.2.2exit

exit手册内容   exit是直接结束进程,引起进程终止  它需要一个参数,就是状态(进程退出码)

1.2.3_exit 

_exit手册内容  用于终止进程的系统调用  通过实验我们发现和exit一样都可以终止进程

 1.2.4exit和_exit区别

补充:我们知道只有OS才可以杀掉进程 库和系统调用是上下层的关系 库调用系统调用

相同点:都可以终止进程

不同点:

  • exit是标准C库函数 _exit是系统调用
  • exit会刷新缓冲区 _exit不会刷新缓冲区

实验:通过下面的实验我们也可以验证exit不会刷新缓冲区

2.进程等待

在理解进程等待前,我们先来想一下进程为什么要进行等待呢?

  • 回收子进程资源(处理僵尸进程)
  • 获取子进程退出信息

我们知道当子进程退出时,task_struct不会被释放,需要父进程回收资源,当父进程一直不管时,就可能会造成僵尸进程,可能会出现内存泄露

2.1wait 

手册内容:wait的参数status是一个输出型参数 在后续的waitpid我们会详细了解

wait会等待任意一个子进程 回收成功会返回回收的pid

接下来我们来使用一下wait 

创建一个子进程 让他跑五次 当子进程结束时,让程序暂停10s,这个时候父进程还没有回收资源,所以子进程此时就是僵尸进程,根据子进程状态我们可以看到是Z,父进程回收子进程资源,解决了僵尸进程,返回了子进程的pid,子进程资源被全部释放,剩余父进程,程序再休眠10s,最后父进程进程也结束

 2.2waitpid

pid_t waitpid(pid_t pid, int *status, int options);  waitpid共有三个参数

接下来会一个一个拆开分析:

 2.2.1pid_t pid

pid_id的值有四种

等待指定pid或者等待任意子进程 

 如果等待失败 会出现什么样的情况呢?

2.2.2int *status

输出型参数 存储进程退出时的状态信息 不关心状态信息设置NULL

我们来进行测试一下:发现出现了一些问题

status不能当做整型看待,可以当做位图来看待,前16位不考虑,次8位是退出状态,那么此时应该前7位是0,然后是1,后面还有8个0,因为是2进制,所以应该是2的8次方,也就是256!

当除数为0时就会使程序出现异常

        其实exit code 和 exit signal都存放在子进程的task_struct中,当子进程是僵尸进程,等待父进程通过操作系统调用回收子进程资源,获取子进程的退出信息

        我们在上述的实验是通过位操作来提取信息的,真正的OS是使用宏,其实就是封装了一下位操作

  • WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是
否是正常退出,程序是否异常,=0为真)
  • WEXITSTATUS(status): WIFEXITED非零,提取子进程退出码。(查看进程的
退出码)

2.2.3int options 

补充:

  • 阻塞调用:当一个程序发起操作时,程序会暂停操作,直到这个操作完成并返回结果,在执行操作时,程序不能做任何事,也就是子进程在执行任务时,父进程一直在wait阻塞
  • 非阻塞调用:当一个程序发起操作,不会等操作完成,而是立即返回,执行后续的操作,程序可以定期检查这个操作是否已经完成,这个操作叫做非阻塞轮询

我们从手册里可以看到options是有几个选项的

  • 默认是0:阻塞调用,如果子进程还没有退出父进程就会一直阻塞在那里
  • WNOHANG:非阻塞调用

waitpid的返回值可以是 -1  0  >0

-1表示失败

0表示 调用结束 但是子进程没有退出

>0 子进程结束

非阻塞轮询实验,将waitpid的第三个参数设置为WNOHANG,非阻塞调用,这样父进程就不会一直等待子进程完成任务,而是立即返回,然后定期去询问子进程完成任务了吗?

非阻塞调用实验:我们可以通过函数指针回调函数来操作

通过实验我们可以看到在子进程执行任务时,父进程也在执行其他任务

3.进程替换 exec

进程替换就是OS根据指定的程序文件路径和参数,将新程序的代码和数据加载到当前进程的地址空间中,覆盖原来的进程内容,从而实现进程替换

程序替换错误返回-1 没有成功返回值 

当我们知道程序替换会将原先的程序进行覆盖,我们原先的程序就没有了,所以我们一般会创建子进程去执行程序替换,这样父进程的代码数据也不会丢失了!! 

3.1进程替换的原理

我们先来使用一下execl,我们可以发现第一句printf执行了,然后执行程序替换,然后就没有输出了,我们来了解一下程序替换的原理!其实在上面就已近谈到了,就是将新程序的代码和数据加载到当前进程的地址空间中,覆盖替换原来的进程内容,从而实现进程替换

在程序替换的过程中,并没有创建新的进程

3.2程序替换接口函数

我们在上面的手册中可以看到6个接口函数,接下来我们学习四个 后续的大家肯定就都懂

还有一个是系统命令 execve  我们在上面看到的6个接口函数其实都是需要去调用execve

在上层进行封装 为了应对各种各样的场景 最后会统一转化 调用系统调用execve

3.2.1execl

int execl(const char *path, const char *arg, ...);

execl的l可以看做是一个list,第一个参数就是路径+程序名,第二个参数就是命令,在命令行怎么写,这里我们就怎么写,...是可变参数列表的意思,因为我们不知道命令有几个,最后要以NULL结尾,表明参数已传完!!

 3.2.2 execlp

int execlp(const char *file, const char *arg, ...);

 execlp的l看做list,p看做PATH,第一个参数就是要执行的文件名,execp会自动在环境变量PATH中查找命令,第二个参数就是命令,同上!

3.2.3execv 

int execv(const char *path, char *const argv[]);

execv的v可以看做是一个vector,第一个参数是要执行的路径+文件名,第二个参数是一个指针数组,也就是命令行参数表 

3.2.4execvp

int execvp(const char *file, char *const argv[]);

execvp的v可以理解为vector,p理解为PATH,第一个参数就是要执行的文件,第二个是指针数组,就是指命令行参数表,相信大家看到这里一看就看懂了!!

3.2.5  execvpe

int execvpe(const char *file, char *const argv[], char *const envp[]);

execvpe的v可以看做vector,e看做environment,第一个参数就是要执行的文件,第二个就是命令行参数表,第三个也是一个指针数组,是环境变量表,这里的环境变量表会进行覆盖替换父进程的环境变量表,当然也有方法在原始的环境变量表的基础上进行添加!!

补充 

putenv 添加环境变量的参数

envrion 访问当前环境的整个环境列表

解决方案 :

  • 不使用需要传带env的参数 直接进行putenv
  • 使用传env的参数 putenv  envrion

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

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

相关文章

iOS开发架构——MVC、MVP和MVVM对比

文章目录 前言MVC(Model - View - Controller)MVP(Model - View - Presenter)MVVM(Model - View - ViewModel) 前言 在 iOS 开发中,MVC、MVVM、和 MVP 是常见的三种架构模式,它们主…

0506--01-DA

36. 单选题 在娱乐方式多元化的今天,“ ”是不少人(特别是中青年群体)对待戏曲的态度。这里面固然存在 的偏见、难以静下心来欣赏戏曲之美等因素,却也有另一个无法回避的原因:一些戏曲虽然与观众…

关于Java多态简单讲解

面向对象程序设计有三大特征,分别是封装,继承和多态。 这三大特性相辅相成,可以使程序员更容易用编程语言描述现实对象。 其中多态 多态是方法的多态,是通过子类通过对父类的重写,实现不同子类对同一方法有不同的实现…

【Trea】Trea国际版|海外版下载

Trea目前有两个版本,海外版和国内版。‌ Trae 版本差异 ‌大模型选择‌: ‌国内版‌:提供了字节自己的Doubao-1.5-pro以及DeepSeek的V3版本和R1版本。海外版:提供了ChartGPT以及Claude-3.5-Sonnet和3.7-Sonnt. ‌功能和界面‌&a…

Missashe考研日记-day33

Missashe考研日记-day33 1 专业课408 学习时间:2h30min学习内容: 今天开始学习OS最后一章I/O管理的内容,听了第一小节的内容,然后把课后习题也做了。知识点回顾: 1.I/O设备分类:按信息交换单位、按设备传…

链表的面试题3找出中间节点

来来来,接着继续我们的第三道题 。 解法 暴力求解 快慢指针 https://leetcode.cn/problems/middle-of-the-linked-list/submissions/ 这道题的话,思路是非常明确的,就是让你找出我们这个所谓的中间节点并且输出。 那这道题我们就需要注意…

linux磁盘介绍与LVM管理

一、磁盘基本概述 GPT是全局唯一标识分区表的缩写,是全局唯一标示磁盘分区表格式。而MBR则是另一种磁盘分区形式,它是主引导记录的缩写。相比之下,MBR比GPT出现得要更早一些。 MBR 与 GPT MBR 支持的磁盘最大容量为 2 TB,GPT 最大支持的磁盘容量为 18 EB,当前数据盘支持…

突破测试环境文件上传带宽瓶颈!React Native 阿里云 OSS 直传文件格式问题攻克二

上一篇我们对服务端和阿里云oss的配置及前端调用做了简单的介绍,但是一直报错。最终判断是文件格式问题,通常我们在reactnative中用formData上传, formData.append(file, {uri: file, name: nameType(type), type: multipart/form-data});这…

Spring Boot 中 @Bean 注解详解:从入门到实践

在 Spring Boot 开发中,Bean注解是一个非常重要且常用的注解,它能够帮助开发者轻松地将 Java 对象纳入 Spring 容器的管理之下,实现对象的依赖注入和生命周期管理。对于新手来说,理解并掌握Bean注解,是深入学习 Spring…

TCP 协议设计入门:自定义消息格式与粘包解决方案

目录 一、为什么需要自定义 TCP 协议? TCP粘包问题的本质 1.1 粘包与拆包的定义 1.2 粘包的根本原因 1.3 粘包的典型场景 二、自定义消息格式设计 2.1 协议结构设计 方案1:固定长度协议 方案2:分隔符标记法 方案3:长度前…

了解一下OceanBase中的表分区

OceanBase 是一个高性能的分布式关系型数据库,它支持 SQL 标准的大部分功能,包括分区表。分区表可以帮助管理大量数据,提高查询效率,通过将数据分散到不同的物理段中,可以减少查询时的数据扫描量。 在 OceanBase 中操…

多线程网络编程:粘包问题、多线程/多进程服务器实战与常见问题解析

多线程网络编程:粘包问题、多线程/多进程服务器实战与常见问题解析 一、TCP粘包问题:成因、影响与解决方案 1. 粘包问题本质 TCP是面向流的协议,数据传输时没有明确的消息边界,导致多个消息可能被合并(粘包&#xf…

大模型主干

1.什么是语言模型骨架LLM-Backbone,在多模态模型中的作用? 语言模型骨架(LLM Backbone)是多模态模型中的核心组件之一。它利用预训练的语言模型(如Flan-T5、ChatGLM、UL2等)来处理各种模态的特征,进行语义…

[创业之路-350]:光刻机、激光器、自动驾驶、具身智能:跨学科技术体系全景解析(光-机-电-材-热-信-控-软-网-算-智)

光刻机、激光器、自动驾驶、具身智能四大领域的技术突破均依赖光、机、电、材、热、信、控、软、网、算、智十一大学科体系的深度耦合。以下从技术原理、跨学科融合、关键挑战三个维度展开系统性分析: 一、光刻机:精密制造的极限挑战 1. 核心技术与学科…

SVTAV1 编码函数 svt_aom_is_pic_skipped

一 函数解释 1.1 svt_aom_is_pic_skipped函数的作用是判断当前图片是否可以跳过编码处理。 具体分析如下 函数逻辑 参数说明:函数接收一个指向图片父控制集的指针PictureParentControlSet *pcs, 通过这个指针可以获取与图片相关的各种信息,用于判断是否跳…

【Redis新手入门指南】从小白入门到日常使用(全)

文章目录 前言redis是什么?定义原理与特点与MySQL对比 Redis安装方式一、Homebrew 快速安装 Redis(推荐)方式二、源码编译安装redisHomebrew vs 源码安装对比 redis配置说明修改redis配置的方法常见redis配置项说明 redis常用命令redis服务启…

Linux grep 命令详解及示例大全

文章目录 一、基本语法二、常用选项及示例1. 基本匹配:查找包含某字符串的行2. 忽略大小写匹配 -i3. 显示行号 -n4. 递归查找目录下的文件 -r 或 -R5. 仅显示匹配的字符串 -o6. 使用正则表达式 -E(扩展)或 egrep7. 显示匹配前后行 -A, -B, -C…

【排序算法】快速排序(全坤式超详解)———有这一篇就够啦

【排序算法】——快速排序 目录 一:快速排序——思想 二:快速排序——分析 三:快速排序——动态演示图 四:快速排序——单趟排序 4.1:霍尔法 4.2:挖坑法 4.3:前后指针法 五:…

【platform push 提示 Invalid source ref: HEAD】

platform push 提示 Invalid source ref: HEAD 场景:环境:排查过程:解决: 场景: 使用platform push 命令行输入git -v 可以输出git 版本号,但就是提示Invalid source ref: HEAD,platform creat…

x-cmd install | Tuistash - Logstash 实时监控,告别图形界面,高效便捷!

目录 核心优势,一览无遗安装适用场景,广泛覆盖功能亮点,不容错过 还在为 Logstash 的监控而头疼吗?还在频繁切换图形界面查看数据吗?现在,有了 Tuistash,一切都将变得简单高效! Tui…