Linux控制---进程程序替换

       前言:前面我们学洗了Linux进程退出的相关知识,了解了什么是进程退出,已经进程等待的相关话题,今天,我们来学习Linux中的进程程序替换,进程程序替换在Linux中可以用于实现新程序的启动、程序升级、多进程程序和程序恢复等多种应用。

目录

1、进程程序替换

什么是程序替换?

替换原理

单个进程的程序替换(无父子进程)

execl函数

程序替换原理详述

父子进程中的程序替换

替换进程如何得知要从程序的最开始开始执行?又如何得知最开始的地方在哪里?

替换程序覆盖性

exec函数分类

execlp、execv、execvp函数

程序替换只能替换系统程序?

C语言替换C++或python程序

多文件同时编译的自动化makefile实现

替换自己写的程序

c语言种替换shell脚本语言

环境变量与execle、execvpe函数

定义子进程自己的专属环境变量

execve系统调用


1、进程程序替换

什么是程序替换?

       在我们之前的讲解中,父子进程本质上都在使用同一份代码,这也就相当于父子进程在同一套代码之下完成任务,而我们创建子进程的目的本来就是为了能让子进程完成一些父进程需要其完成的任务,并带给父进程对应的返回结果,但是,如果父子进程在同一套代码逻辑中,那创建子进程不就相当于脱裤子放屁自找麻烦吗?其实,子进程被创建出来,是可以用来执行与父进程不同的程序的,程序替换简单来说就是将正在运行的程序替换为另一个程序。这个过程涉及内存加载新程序到内存中,并更新页表信息,初始化虚拟地址空间,然后将现有PCB的指针指向新的程序,使得现有PCB从头开始调度新的进程运行。需要注意的是,程序替换后,当前进程运行完替换后的程序就会退出,并不会回去运行原先的程序。

替换原理

       用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变

单个进程的程序替换(无父子进程)

execl函数

      execl函数时exec函数中的一种,后面的几种我们稍后会提及,其功能替换一个指定路径的程序,

其中execl的参数,path参数就是替换程序所在的文件路径,arg就是执行命令的若干个参数,比如ls -a -l......,这些都属于这个参数,这里,我们先给出一个最简单的解释,比如我们需要执行“ls -a -l”,那么我们在命令行参数中就按这个顺序输入(“ls”,“-a”,“-l”)就可以了,也就相当于我们在命令行中如何使用,在参数中就如何输入即可,需要注意的是,该函数必须在参数最后加上NULL表示传入参数结束。具体如下面的用例:

我们发现一个现象,一旦我们进行了程序替换,也就是执行了execl函数,该函数之后的语句就不会再被执行了,上面的例子中,execl函数之后的printf函数没能够被执行,这一点就和我们程序替换的原理有关,下面我们就来对程序替换原理进行详细的分析,

程序替换原理详述

       在Linux中,进程程序替换通常指的是使用exec()系列函数来实现的进程替换过程。这个过程包括加载一个全新的程序(代码和数据)到调用进程的地址空间中,并开始执行新程序。这个过程会替换当前进程的内容,原有进程的执行状态和上下文信息会被丢弃。在进程替换发生时,原有进程的代码、数据和资源会被新的进程所取代。该替换过程没有创建新的进程,只是替换原来的进程

父子进程中的程序替换

       前面我们演示的是单进程的程序替换场景,如果在父子进程的模式下又会出现什么样的情况呢?我们知道,父子进程在不进行写操作时是共享同一份代码和数据的,但是如果父进程或者子进程发生了程序替换,那么此时剩下的那个进程就要采用我们之前学过的写时拷贝技术来将原有代码和数据拷贝一份供剩余进程使用,使得两个进程各自保持自己的独立性

替换进程如何得知要从程序的最开始开始执行?又如何得知最开始的地方在哪里?

       当我们采用程序替换的方式引入一个新的程序时,这个程序如何得知其该从哪个位置开始执行,又如何得知其执行的位置在哪里呢?实际上,每个可执行程序在磁盘中的存储,并不是单纯的只是存储代码和数据,可执行程序的二进制文件中,头部有一个专门的表结构,其中专门有一个字段用来表示程序的入口地址,通过将其填充到对应的调用进程的程序计数器pc中,即可达到调用的效果。这里顺便提一嘴,pc指针(eip)是cpu中的一个寄存器,在cpu中只有一个,但是并不是所有的进程只有一个pc指针,寄存器中的内容可以有多份,一个cpu可以有多套内容,分别用来对应不同的内容。

替换程序覆盖性

        我们在上面的代码中不难发现,不论是单个进程的程序替换,还是父子进程的程序替换,被替换的进程在执行exec函数结束后,其后续的代码均不会被执行,此时因为程序被替换,所以被替换程序会被覆盖,导致其后序的代码不会再被执行,这个就是替换程序的覆盖性。

exec函数分类

       前面我们了解到exec函数具有多种,但是各种函数之间的用法和功能却不尽相同,下面我们来介绍几种常见的exec函数:

execlp、execv、execvp函数

程序替换只能替换系统程序?

       上面我们的例子只是针对系统程序进行了替换,但是不代表程序替换只能局限于系统函数,事实上,程序替换还可以替换自己写的程序,这其中包括其他语言的程序(例如c++和python程序)还有shell脚本语言等,下面,我们就来演示一下。

C语言替换C++或python程序

首先,我们来分别编写一个C++和python文件:

多文件同时编译的自动化makefile实现

      当我们想要一次编译两个或两个以上的源文件并形成对应的目标文件时,我们就需要只调用一次makefile工具就能直接将所有源文件全部编译,但是我们知道makefile从上往下扫描的时候默认只形成扫描到的第一个目标文件,所以我们就需要采取一些手段,使其能够同时编译出两份目标文件,我们可以将两份目标文件封装成一个总的目标文件放在makefile首部,这样,默认调用的首个目标文件中就包含了我们需要的两个目标文件,从而达到目的。

比如,我们一次需要形成C和C++的可执行程序时,我们可以采用如下的方式编写makefile:

替换自己写的程序

python程序也是同理,python是一种解释型语言,Python 解释器在运行代码时不会将其编译为机器语言。相反,它会在运行时解释代码,所以,我们不能够在通过makfile编译形成目标文件来形成所谓的“python的可执行程序”了,我们只能通过调用python的解释器来直接解释我们的python文件,具体实现如下:

c语言种替换shell脚本语言

       脚本语言,或称为动态编程语言,是一种解释型语言。它通常用于执行具有复杂逻辑和流程控制的任务,比如网页编程、系统配置、游戏脚本等。其采用系统的bash命令行解释器就可以运行,比如我们可以编写和运行如下的shell脚本,至于如何编写这里先了解即可,这不是我们的重点:

此时,我们可以将其替换为在程序中运行,如下:

      现在,你可以拿着这个和你的朋友装一下了,我们可以在c上运行其他语言的代码,其实不仅是c语言,其他的编程语言都有着类似的程序替换函数,感兴趣的可以去百度一下。

环境变量与execle、execvpe函数

       环境变量一般是具有全局属性的,也就是说,它可以被进程和子进程之间共享,对于父子进程之间,环境变量共用一套无可厚非,并且,我们也知道,父进程的环境变量来源于bash命令行解释器,为了验证bash、父进程和子进程的爷、父、孙的关系,我们可以将父进程中子进程进程替换的代码修改为输出打印环境变量,接着我们利用export向命令行bash进程中加入一个新的临时环境,看其是否会被父进程和子进程所接受和显示,参考代码如下:

接着,我们在命令行导入一个临时环境变量到bash进程中去:

此时,该环境变量就被保存在了bash进程中,接着,我们编译并运行代码,然后,我们可以发现打印出的孙子进程的环境变量中存在我们创建的环境变量(也就是来自“爷爷”进程的环境变量)。

        事实上,父子进程在传递的过程中,子进程是默认继承父进程的去全部的环境变量的,并且不会受到程序替换的影响,前面已经提到,程序替换本质上并没有改变进程的pcb和进程地址空间等内核数据结构,只是替换了物理内存上的代码和数据而已,而环境变量则是随着进程地址空间上的一个字段上保存的,所以,子进程在创建的时候会继承父进程的进程地址空间,也就把父进程的环境变量给继承了下来。

定义子进程自己的专属环境变量

     如果我们的子进程想要定义属于自己的环境变量而不希望再沿用父进程的环境变量,就需要用到我们下面的两个函数了:

例如,此时我们想要修改子进程的被替换程序的环境变量,参考代码如下:

为了方便显示出我们传入命令行参数的效果,我们可以在替换程序中将命令行参数打印出来: 

运行代码,结果如下:

       可以看到,被替换程序的环境变量已经被覆盖式的修改成了我们自己定义的环境变量,注意是覆盖不是新增,那当我们需要新增时怎么办?还记得我们上面给bash添加环境变量时的场景吗?想要给子进程在原来的基础上新增环境变量,我们只需要在其父进程里创建一个临时环境变量就可以了,此时子进程将会继承父进程的环境变量表,包括新增的。

execve系统调用

       execve接口是在Unix和类Unix操作系统中执行新程序的系统调用。事实上,只有execve是真正的系统调用,其它六个函数最终都调用execve,所以execve在man手册 第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。

本篇到这里就结束了,下期,我们将自己动手做一个简单的shell,可以实现简易的指令反馈和操作,模拟在XShell上的各种指令,持续更新......

       真正能给你撑腰的是丰富的知识储备、足够的经济基础,持续稳定的情绪,可控的生活节奏,以后的日子里,希望你多长本事,多看世界,多走些路,把时间花在正事上,变成自己打心底里喜欢的人,世界上任何东西都应该是被吸引来的,而不是强求来的,梧高峰必至,花香蝶自来。

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

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

相关文章

利用Vue+Echarts完成可视化任务

文章目录 任务一:用柱状图展示消费额最高的省份(一)提出任务(二)准备工作1、利用postman访问接口数据2、安装node.js3、输入更换镜像源为淘宝源4、清除npm缓存5、安装vue脚手架6、创建vue项目7、启动vue项目 任务一&am…

C语言判断闰年(ZZULIOJ1028: I love 闰年!)

题目描述 根据一个年份,判断是否是闰年。 输入:输入为一个整数,表示一个年份。 输出:如果是闰年,输出"Yes",否则输出"No"。输出单独占一行。 样例输入 Copy 2012 样例输出 Copy Yes 分…

UE5 - UI Material Lab 学习笔记

1、学习资料收集 UI Material Lab : https://www.unrealengine.com/marketplace/zh-CN/product/ui-material-lab 视频1:https://www.bilibili.com/video/BV1Hm4y1t7Kn/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 视…

关闭RecyclerView惯性滚动,以及多个RecyclerView在嵌套滚动中的注意事项

前言: 当前RecyclerView 下拉到顶部 或者 上拉到底部时,虽然滚动列表停止了,但惯性任务并没有结束,一些特殊需求可能受到影响,需要手动停止。 1. RecyclerView源码 调用 rv.stopScroll() 停止; 2. Recycl…

网工内推 | 急聘网络运维,周末双休,厂商认证优先

01 湖北华特信息技术有限公司 招聘岗位:网络运维工程师(双休急聘) 职责描述: 1、 负责局域网交换机、路由器、防火墙等设备维护; 2、熟悉OSPF动态路由协议,有实施或维护经验; 3、 熟悉网络架构…

Java方法中不使用的对象应该手动赋值为NULL吗?

在java方法中,不使用的对象是否应该手动赋值为null?我们先来通过一个示例看一下。 垃圾回收示例一 public class GuoGuoTest {public static void main(String[] args) {byte[] placeholder new byte[64 * 1024 * 1024];System.gc();} } 上面代码向内…

Radiology 谈人工智能在放射学领域的10个预测方向 [文献阅读]

人工智能(AI)和信息学正在改变放射学。十年前,没有哪个专家会预测到今天放射人工智能行业的蓬勃发展,100多家人工智能公司和近400种放射人工智能算法得到了美国食品和药物管理局(FDA)的批准。 不到一年前,即使是最精明的预言家也不会相信这些…

kubernetes资源管理

资源管理 资源管理介绍 在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes。 kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务,所谓的部署服务,其实就是在kubernetes集…

Java设计模式-结构型模式-适配器模式

适配器模式 适配器模式应用场景案例类适配器模式对象适配器模式接口适配器模式适配器模式在源码中的使用 适配器模式 如图:国外插座标准和国内不同,要使用国内的充电器,就需要转接插头,转接插头就是起到适配器的作用 适配器模式&…

unity使用vs进行c#代码提示,查看F12unity元代码

unity关联vs 在vs中让cs.meta显示,鼠标右键,包含在内 提示GameObject类了 感谢下面这位的提示https://zhuanlan.zhihu.com/p/551119106

esp-01刷固件/下载软件到内部单片机的方法

此文章为转载,非原创 一、准备 需要准备三个东西: 1.esp模块。ESP-01 和 ESP-01s 的引脚及 flash 容量基本完全兼容,只是内部硬件设计粗糙与否的区别,所以理论上都适用。 2.官方固件。此部分可以从安信可官方教程中下载&#xff0…

腾讯待办停止运营怎么办?导出的ics文件数据怎么打开查看

待办提醒类工具是日常办公及生活中必不可少的工具,使用待办提醒类工具可以记录很多容易忘记的事情,其可以帮助大家轻松管理各项事务和提高办事的效率。而随着工作的不断变动,大家选择待办提醒类工具也会不断的发生改变。 比如就拿我自己的使…

【算法总结】归并排序专题(刷题有感)

思考 一定要注意归并排序的含义,思考归并的意义。 主要分为两个步骤: 拆分 每次对半分(mid l r >> 1)输入:raw整块,输出:raw左块 raw右块 合并 每次都要对raw左块、 raw右块按照某种规则进行合并输入&#xf…

2023.11.15-hivesql之炸裂函数explode练习

把一个容器的多个数据炸裂出单独展示: explode(容器) 需求:将NBA总冠军球队数据使用explode进行拆分&#xff0c;并且根据夺冠年份进行倒序排序。 1.建表 --step1:建表 create table the_nba_championship(team_name string,champion_year array<string> ) row format…

Minio安装

环境 centos8&#xff0c;关闭防火墙 minio-20231101183725版本 参考官网&#xff1a;部署 MinIO&#xff1a;单节点单硬盘 — 适用于 Linux 的 MinIO 对象存储 单例 下载rpm&#xff0c;用中国镜像 wget https://dl.minio.org.cn/server/minio/release/linux-amd64/arch…

C语言判断水仙花数(ZZULIOJ1027:判断水仙花数)

题目描述 春天是鲜花的季节&#xff0c;水仙花就是其中最迷人的代表&#xff0c;数学上有个水仙花数&#xff0c;他是这样定义的&#xff1a;“水仙花数”是指一个三位数&#xff0c;它的各位数字的立方和等于其本身&#xff0c;比如153135333。 现在要求输入一个三位数&#…

数据分析 - 分散性与变异的量度

全距 - 极差 处理变异性 方差度量 数值与均值的距离&#xff0c;也就是数据的差异性 标准差描述&#xff1a;典型值 和 均值的距离的方法&#xff0c;数据与均值的分散情况

windows 安装 Oracle Database 19c

目录 什么是 Oracle 数据库 下载 Oracle 数据库 解压文件 运行安装程序 测试连接 什么是 Oracle 数据库 Oracle数据库是由美国Oracle Corporation&#xff08;甲骨文公司&#xff09;开发和提供的一种关系型数据库管理系统&#xff0c;它是一种强大的关系型数据库管理系统…

用这个平台制作电子杂志,,还能实时分享,太方便啦!

在我们看电子杂志的时候&#xff0c;总会觉得图文效果有点枯燥&#xff0c;如果能做出翻页书效果的电子杂志&#xff0c;还给人一种身临其境的真实翻书感就好了。 其实制作这种翻页电子杂志很简单&#xff0c;不需要下载安装任何软件&#xff0c;只需登录FLBOOK这个平台 &…

OCR文字识别标注小助手

目录 背景 工具界面 操作 1、选择目录 2、更改为正确的信息 3、保存 4、说明 项目 代码 下载 背景 为什么要写这么一个小工具呢&#xff1f;因为要对文字进行标注。 为什么对文字进行标注呢&#xff1f;因为要重新训练识别。 为什么要重新训练识别呢&#xff1f;因…