Linux系统编程——进程替换

目录

前言

二、进程程序替换的概念

三、进程程序替换的原理

​编辑

  四、为什么需要进行进程程序替换

五、如何进行进程程序替换

1、进程替换函数:

1)execl()函数

2)execv()函数

3) execlp()函数

 4) execvp()函数

5)execle函数

6)excpve()函数

7)execve()*


前言

一般情况下,对应的语言写的程序只能调用对应的语言的接口,对于其它类型的语言的接口,如C++就不能 调用java或者python的接口,那如果我们想要调用别人的接口怎么办?所以进程程序替换就能很好的解决这个问题,这样我们就可以使用现成其他语言接口的程序而不用费力地去再实现一个,很大程度上能减少我们的编程成本。

二、进程程序替换的概念

进程程序替换按照字面意思理解就是使用一个新的程序来替换掉原来的程序,此时进程将执行新程序的代码,而不再执行原有程序的代码。一般情况下,我们都是在父进程中fork一个子进程出来,让子进程去执行新程序的代码。其实不单是子进程,当前进程也可以发生进程替换。

三、进程程序替换的原理

  • 进程替换前,fork()创建子进程之后,子进程和父进程共享代码和数据的:

我们之前在父子进程那一篇讲到过,当父子进程都没有修改代码和数据,因此父子进程的代码和数据是指向同一块内容的,是共享的。当有一方进行写入数据时,就会发生写时拷贝。如果想要执行不同的代码,此时就需要进行进程程序替换。

 假设一开始父子进程都执行的是可执行程序A,如果后面想要执行B程序,那么此时就需要进行进程程序替换,发生替换的时候,操作系统会调用系统调用接口,首先操作系统会将父进程的代码和数据拷贝一份,然后将B程序加载到内存中,重新建立子进程的页表,更新子进程的页表中的映射关系,但是这里修改的只是子进程页表中的物理地址那一栏,此时的父子进程的虚拟地址那一栏还是一样的,只不过操作系统修改了虚拟地址和物理地址之间的映射关系,从而实现了父子进程的代码分离。此时父子进程是互不干扰的。

进程替换后: 

所以进程程序替换就是想让子进程去执行其他磁盘的文件,其本质还是将指定程序的代码和数据加载到指定位置(即覆盖掉原来的自己的代码和数据。)

  四、为什么需要进行进程程序替换

我们在Linux下进行系统编程的时候,我们在创建子进程后,一般是让它执行父进程的代码片段或者让子进程单独去执行磁盘中的其他程序,其他程序可能设计:C/C++、java等不同语言的程序。想让子进程处理后面的事的时候就需要进行进程程序替换。

比如我们使用的bash、zsh等shell,其实都是运用了进程替换的方式才调用了非常多的命令,就像我们在进程中刚开始说的一样,我们在命令行中运行的每一个命令的父进程都是bash,即每次都是bash创建一个子进程来代替它执行命令。

五、如何进行进程程序替换

进程程序替换是由操作系统通过调用系统接口来实现的,但是我们需要提前明确一个点,就是使用这些调用接口的注意事项,我们在替换程序的时候,肯定需要知道这个程序在哪里吧,在找到这个程序之后,我们还需要知道如何去执行这个程序,就像shell命令行中输入命令一样,在命令后面可能还带有许多选项。

1、进程替换函数:

操作系统中有着六种以exec开头的函数,统称exec函数

  • 这些函数如果调用成功则加载新的程序从启动代码开始执行。如果调用出错则返回-1;所以说exec()函数只有出错的返回值而没有成功的返回值。 
  • 可以看到这些函数名字都有着很多的共同点:同样都是exec开始的,后面跟不同的字母以表示不同的功能。
  • 再看他们的参数,我们都可以大概猜出来一二,比如path表示替换的程序路径,arg我们在环境变量一篇中见过,表示如何执行该命令,就像shell命令行里命令后跟的选项一样,如 ls -a的“-a”。“...”表示的是可变参数,file表示的是替换程序的文件名,envp表示的是环境变量。
  • l(list):表示参数采用列表,
  • v(vector):表示参数使用数组
  • p(path):自动搜索环境变量PATH
  • e(env):表示自己维护环境变量

1)execl()函数

我们fork()出一个子进程让它去执行shell命令中的ls命令,并且带上选项参数。我们使用execl函数,传的参数是ls命令的路径和可执行命令及选项参数,并且要以NULL结尾(告诉函数传参结束)

2)execv()函数

该函数和execl相比较就差在参数存放的方式,后者是以列表方式存放,而该函数是以数组方式存放的

 需要注意的是该函数使用的是字符指针数组,不是字符串列表,数组中的字符串是常量字符串,即const char类型的,而字符指针数组中存放的又是char类型的是支持修改的,因此这里需要将const char强转为char类型。

3) execlp()函数

该函数和execl()相比就是多了个P,这里的P指的就是PATH,指的是系统直接到环境变量PATH中去寻找对应的程序,所以在第一个参数中我们并不需要传路径。

 

 4) execvp()函数

5)execle函数

这个函数与前几个函数相比多了一个e,那么这个e是什么呢?e表示的是环境变量,这个接口的作用是可以给想要执行的程序传入自己定义的环境变量。第三个参数可以覆盖式的将想要传的环境变量传给想要执行的程序,一般两种情况,第一种就是直接传入自定义的环境变量,第二种就是通过environ,并将自定义的环境导出为系统的环境变量,那么这样就可以了

 

我们使用了environ变量来遍历并打印出当前进程的环境变量。environ是一个指向字符串数组的指针,每个字符串都是一个环境变量,格式为"NAME=VALUE"。这个数组以一个空指针结尾。  

makefile文件(多文件下)

 

运行结果

 

但是这里并不验证将enviorn环境变量列表传入了env_test中,因为我们如果执行env_test的话还是会有一样的结果。 

下面我们自定义一个环境变量列表,观察实验结果

然后env_test不变,观察实验结果

 

  •  可以证实,这个envp参数的作用是接收从父进程传来的环境变量列表
  • 在第一个程序中,我们没有自定义环境变量,子进程运行的env_test程序的环境变量是从父进程传来的。但这个实验现象不明显。
  • 第二个程序中,我们自定义了环境变量,并且利用execle函数传给env_test程序,使用environ打印它就出现了我们所定义的环境变量。
  • 所以说我们前面说的在创建子进程时,子进程会继承父进程的环境变量,即父进程的环境变量列表传入了子进程,且我们通过实验看到使用execle()函数进行进程替换时,子进程的环境变量,完全取决于父进程传什么环境列表。
  • 其他的不带envp参数的进程替换的接口,默认给替换的进程传入的是被替换进程的环境变量列表。
  • 值得注意的是,execle()函数在传入时,这个环境是覆盖式地传入,并不是新增式地传入,这也就是为什么我们第二个实验打印出来地只有自己定义的环境变量,因为它们把之前的环境变量都覆盖掉了。

如何不覆盖式地添加新的环境变量传给子进程呢? 

 putenv()函数

调用方法:只需要在参数中传入需要在环境变量中添加的环境变量即可。

 

 

当子进程地环境变量中多了一个环境变量后,父进程地环境变量中是不是也会多出来一个呢?

不会,子进程的环境变量继承于父进程,修改之后是不影响的。 

6)excpve()函数

 

看这个函数的参数,也没有什么新颖的,跟上面的函数也都是大同小异,所以就不演示了。

7)execve()*

int execve(const char *filename, char *const argv[], char *const envp[]);

 上面的六个函数本质上都调用了该函数,所以是该函数的封装,是系统真正的调用接口。

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

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

相关文章

探索HarmonyOS:一键掌握Router与NavPathStatck的传参和页面回调技巧

路由的选择 HarmonyOS提供两种路由实现的方式,分别是 Router 和 NavPatchStack。两者使用场景和特效各有优劣。 组件适用场景特点备注Router模块间与模块内页面切换通过每个页面的url实现模块间解耦NavPathStack模块内页面切换通过组件级路由统一路由管理 什么时候使…

go使用mysql实现增删改查操作

1、安装MySQL驱动 go get -u github.com/go-sql-driver/mysql2、go连接MySQL import ("database/sql""log"_ "github.com/go-sql-driver/mysql" // 导入 mysql 驱动 )type Users struct {ID intName stringEmail string }var db *sql.DBfu…

ffmpeg安装(windows)

ffmpeg安装-windows 前言ffmpeg安装路径安装说明 前言 ffmpeg的安装也是开箱即用的,并没有小码哥说的那么难 ffmpeg安装路径 这就下载好了! 安装说明 将上面的bin目录加入到环境变量,然后在cmd中测试一下: C:\Users\12114\Desktop\test\TaskmgrPlayer\x64\Debug>ffmpe…

FPGA存在的意义:为什么adc连续采样需要fpga来做,而不会直接用iic来实现

FPGA存在的意义:为什么adc连续采样需要fpga来做,而不会直接用iic来实现 原因ADS111x连续采样实现连续采样功能说明iic读取adc的数据速率 VS adc连续采样的速率adc连续采样的速率iic读取adc的数据速率结论分析 FPGA读取adc数据问题一:读取adc数…

《Vue零基础入门教程》第十四课:列表渲染

往期内容 《Vue零基础入门教程》第六课:基本选项 《Vue零基础入门教程》第八课:模板语法 《Vue零基础入门教程》第九课:插值语法细节 《Vue零基础入门教程》第十课:属性绑定指令 《Vue零基础入门教程》第十一课:事…

Redis主从架构

Redis(Remote Dictionary Server)是一个开源的、高性能的键值对存储系统,广泛应用于缓存、消息队列、实时分析等场景。为了提高系统的可用性、可靠性和读写性能,Redis提供了主从复制(Master-Slave Replication&#xf…

学成在线day08

部署静态页面 相关操作:https://mx67xggunk5.feishu.cn/wiki/FLozwxrrxihTJbkyTHgchDt4nUc nginx的最终配置文件: worker_processes 1; events {worker_connections 1024; } http {include mime.types;default_type application/octet-strea…

Oracle数据恢复—Oracle数据库sysaux文件损坏的数据恢复案例

Oracle数据库故障&分析: 一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求…

ArraList和LinkedList区别

文章目录 一、结构不同二、访问速度三、插入和删除操作的不同1、决定效率有两个因素:数据量和位置。2、普遍说法是“LinkedList添加删除快”,这里是有前提条件的 四、内存占用情况五、使用场景六、总结 一、结构不同 LinkedList:它基于双向链…

B站狂神说Mybatis+Spring+SpringMVC整合理解(ssm框架整合)

文章目录 0.写在前面(对mybatis,spring的理解)(不看可跳过)0.1 为什么需要mybatis0.2 为什么需要spring0.3为什么需要springmvc 1.新建ssmbuild数据库2.新建Maven项目3.初始化步骤3.1 配置下载maven依赖,构建资源导出3.2 连接数据库3.3建包&a…

Java抛出自定义运行运行

1.重新生成异常的.java文件 Empty:空 Exception:异常 加起来就是 空指针异常的文件 2.打上extends 运行的异常(异常的类型) 3.点击ctrlo,选着这两个快捷重写 4.在需要抛出异常的地方写上:th…

项目二技巧一

目录 nginx实现根据域名来访问不同的ip端口 配置Maven私服 快照版和发布版的区别 快照版本(Snapshot) 发布版本(Release) 导入发布版的父工程 理清楚授权规则 一.首先浏览器发送/manager/**路径请求 第二步:构造…

简单获取json预览

data: JSON 数据。 collapsedNodeLength: 对象或数组的长度超过此阈值时会折叠 deep: json路径深度超过此值时会折叠 showLineNumber: 显示左侧行号 showIcon: 显示图标。 virtual: 使用虚拟滚动 height: 使用虚拟滚动时列表的高度 itemHeight: 使用虚拟滚动时节点的高…

使用zabbix监控k8s

一、 参考文献 小阿轩yx-案例:Zabbix监控kubernetes云原生环境 手把手教你实现zabbix对Kubernetes的监控 二、部署经验 关于zabbix监控k8s,总体来说是分为两块内容,一是在k8s集群部署zabbix-agent和zabbix- proxy。二是在zabbix进行配置。…

第三方Express 路由和路由中间件

文章目录 1、Express 应用使用回调函数的参数: request 和 response 对象来处理请求和响应的数据。2、Express路由1.路由方法2.路由路径3.路由处理程序 3. 模块化路由4. Express中间件1.中间件简介2.中间件分类3.自定义中间件 1、Express 应用使用回调函数的参数&am…

港科夜闻 |香港科大推出 InvestLM生成式人工智能平台,支持金融中小企应用AI技术潜力...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大推出 InvestLM生成式人工智能平台,支持金融中小企应用AI技术潜力。香港科大商学院继去年研究团队成功开发本港首个专为金融界而设、应用于生成式人工智能(生成式AI)的开源大语言模型InvestLM后&#…

[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker pull线上镜像方式构建编译环境

T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求: 硬件: 设备容量备注硬盘>500G多版本系统测试,必须固态,否则编译卡死硬盘>300G单系统…

Git 快速入门:全面了解与安装步骤

Git 快速入门:全面了解与安装步骤 一、关于Git 1.1 简介 Git 是一个开源的分布式版本控制系统,由 Linus Torvalds 于 2005 年创建,最初是为了更好地管理 Linux 内核开发而设计。 Git用于跟踪计算机文件的变化,特别是源代码文件…

基于Java Springboot奶茶点餐微信小程序

一、作品包含 源码数据库万字文档全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA,微信开发者工具 数据…

vulnhub靶场【哈利波特】三部曲之Fawkes

前言 这次的靶机与前面不同,这里涉及到缓冲区溢出等 这个靶机也让我知道薄弱点了,缓冲溢出这方面之前接触少,所以刚拿到这个靶机打开后,人蒙了,在网上查阅好多资料,也只是浅学一下,这里主要也是…