Linux--进程控制(2)--进程的程序替换(夺舍)

目录

进程的程序替换

0.相关函数

1.先看现象

 2.解释原理

3.将代码改成多进程版

 4.使用其它的替换函数,并且认识函数参数的含义

5.其它


进程的程序替换


0.相关函数

 关于进程替换我们需要了解的6个函数:

函数解释:

  • 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
  • 如果调用出错则返回-1
  • 所以exec函数只有出错的返回值而没有成功的返回值

命名理解:

  • l(list) : 表示参数采用列表
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量

exec调用举例如下:

int main()
{char* const argv[] = { "ps", "-ef", NULL };char* const envp[] = { "PATH=/bin:/usr/bin", "TERM=console", NULL };execl("/bin/ps", "ps", "-ef", NULL);// 带p的,可以使用环境变量PATH,无需写全路径execlp("ps", "ps", "-ef", NULL);// 带e的,需要自己组装环境变量execle("ps", "ps", "-ef", NULL, envp);execv("/bin/ps", argv);// 带p的,可以使用环境变量PATH,无需写全路径execvp("ps", argv);// 带e的,需要自己组装环境变量execve("/bin/ps", argv, envp);exit(0);
}

      

1.先看现象

先来看一段代码:

运行结果:我们发现让程序使用exec*函数,可以执行起来新的程序

我们还发现,执行玩这条语句,后面的语句都不执行了


 2.解释原理

我们都知道,我们的可执行程序运行起来就变成了进程。

创建进程=创建内核相关管理的数据结构(task_struct,mm_struct,页表)+代码和数据。

        内存管理的数据,如代码段、数据段和堆栈等,则包含了程序执行所需的数据和代码。

        当我们谈论进程替换时,实际上是指用一个新的程序来完全替代当前进程的内存映像,也就是替换掉原有的代码段、数据段和堆栈等内存管理的数据。而CPU执行的上下文,如程序计数器、寄存器和程序状态字等,则会被新的程序所继承。这样,新的程序就可以从它的入口点开始执行,就像它是一个全新的进程一样。(但他不是一个全新的程序,因为这个过程并没有创建新的进程,只是替换掉了原进程的数据和代码,依旧使用原来进task_struct,mm_struct,页表) 用老进程的壳子执行新的代码和数据。(可以理解成被夺舍了)

        exec*函数族就是用来实现这种进程替换的系统调用。这些函数会根据指定的文件名找到可执行的文件,并用它来替换当前进程的内容。换句话说,它们会在当前进程内部执行一个全新的可执行文件。

 当你调用一个exec*函数时,它会做以下几件事情:

  1. 查找并加载新的程序文件到内存。
  2. 清除当前进程的内存映像,包括代码段、数据段和堆栈等。
  3. 将新的程序的代码和数据加载到当前进程的内存空间中。
  4. 更新程序计数器,使其指向新程序的入口点。
  5. 开始执行新程序。       

        值得注意的是,exec*函数执行成功就不需要关心它的返回值了。这是因为调用进程的实体,包括代码段、数据段和堆栈等,都已被新的内容所取代,只留下进程ID等一些表面上的信息保持原样。所以,一旦exec*函数执行成功,当前进程就已经被新的程序所替代,原有的程序已经不再存在。(这就是为什么在上面执行那段代码的时候,程序最后没有执行printf("test .... end!\n");)

        总的来说,exec*函数族是Linux环境下实现进程替换的重要工具。它们通过替换当前进程的内存映像来执行新的程序,使得我们可以在一个进程中执行不同的程序,从而实现程序的切换和执行流程的改变。
 


3.将代码改成多进程版

        我想进行程序替换,但我不想影响我父进程本身,这时候我们就可以把代码改成多进程版本,让子进程去进行替换,父进程进行wait就行了。

代码示例:

运行结果:


 4.使用其它的替换函数,并且认识函数参数的含义

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

path : 我们要执行程序,需要带路径(怎么找到程序,你得告诉我)(你想执行谁)

list列表:在命令中怎么执行,就这么传参(标准情况)(你想怎么执行)

int execv(const char *path, char *const argv[])
path :和上面的一样

argv:是一个指针数组,直接把参数传到数组里

用法:

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

p:用户可以不传要执行的文件路径(但是要穿文件名),查找这个程序,系统会自动在环境变量PATH中进行查找。

用法:

int execle(const char *path, const char *arg, ...,char *const envp[]);
int execvpe(const char *path, char *const argv[], char *const envp[]);

这里的e:表示环境变量(environment)

上面的程序替换,我们替换的都是系统命令,可不可以替换我们自己的程序呢?

这是我们在C语言程序调用C++程序的方式

我们在C++程序中写的

编译c和c++程序运行c程序:我们成功的替换了我们自己的程序

接着谈环境变量。接上面代码:这一次我们将环境变量给了execvpe函数

我们在c++程序中接收了,命令行参数表和环境变量表并将它们打印出来了:

编译运行看一下效果:

结论:我们平时自己运行的程序,命令行参数和环境变量,是父进程通过将自己的环境变量表和命令行参数表通过,execvpe函数传递来的。而我的父进程本身就有一批环境变量!!从bash来。(我们是可以将bash的环境变量表直接传给子进程的,就不做演示了)。


5.其它

         事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。

下图exec函数族 一个完整的例子:

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

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

相关文章

通过filebeat实现对docker服务的通用日志收集

平台 依赖 linux docker docker-compose 或者 docker compose 镜像 docker.elastic.co/beats/filebeat:8.12.2 docker.elastic.co/beats/kibana:8.12.2 docker.elastic.co/beats/elasticsearch:8.12.2 正文 背景 对于有自建机房的公司来说,如果公司的运维技术…

Stable Diffusion使用ControlNet:IP-Adapter实现图片风格迁移

IP-Adapter 全称是 Text Compatible Image Prompt Adapter for Text-to-Image Diffusion Models(文本到图像扩散模型的文本兼容图像提示适配器),是腾讯研究院出品的一个新的ControlNet模型,旨在使预训练的文本到图像扩散模型能够生…

【06】JAVASE-数组讲解【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture:波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。…

最全GPTs使用教程+Prompt预设词教程

使用指南 直接复制使用 可以前往已经添加好Prompt预设的AI系统测试使用(可自定义添加使用) https://ai.sparkaigf.com 现已支持GPTs 雅思写作考官 我希望你假定自己是雅思写作考官,根据雅思评判标准,按我给你的雅思考题和对应…

从零入门区块链和比特币(第三期)

欢迎来到我的区块链与比特币入门指南!如果你对区块链和比特币感兴趣,但不知道从何开始,那么你来对地方了。本博客将为你提供一个简明扼要的介绍,帮助你了解这个领域的基础知识,并引导你进一步探索这个激动人心的领域。…

一些基础知识FK

1. 群体稳定性指数PSI 通过 PSI(Population Stability Index) 指标,可以得到不同样本下,模型在各分数段分布的稳定性。用于衡量两个群体(比如两个时间点、两个子群体等)之间稳定性的指标。通常PSI被用于评估信用风险模型、预测模型等在不同时间点或不同群…

安装配置Maven(idea里面配置)

放在这个路径下(如果需要可以免费发给你,dd我就好了) D:\IearnSoftware\maven\apache-maven-3.6.1-bin.zip(我自己的路径下面,防止忘记) 1.首先测试maven在不在,配置对不对 mvn -v 这样就是成…

STM32HAL库++ESP8266+cJSON连接阿里云物联网平台

实验使用资源:正点原子F1 USART1:PA9P、A10(串口打印调试) USART3:PB10、PB11(WiFi模块) DHT11:PG11(采集数据、上报) LED0、1:PB5、PE5&#xff…

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言:基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

第72天:漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

案例一:某 APP-Web 扫描-常规&联动-Burp&Awvs&Xray Acunetix 一款商业的 Web 漏洞扫描程序,它可以检查 Web 应用程序中的漏洞,如 SQL 注入、跨站脚本攻击、身份验证页上的弱口令长度等。它拥有一个操作方便的图形用户界 面&#…

实验8 NAT配置

实验8 NAT配置 一、 原理描述二、 实验目的三、 实验内容1.实验场景2.实验要求 四、 实验配置五、 实验步骤2.静态NAT配置3.NAT Outbound配置4.NAT Easy-IP配置 一、 原理描述 2019年11月26日,全球43亿个IPv4地址正式耗尽,这意味着没有更多的IPv4地址可…

Taro引入echarts【兼容多端小程序(飞书/微信/支付宝小程序)】

近期接到公司新需求,开发飞书小程序,并且原型中含有大量的图表,本想使用飞书内置图表组件 —— chart-space,但官方表示已经停止维护了,无奈之下,只能另寻他路,于是乎,图表之王&…

【Godot4.2】自定义Todo清单类 - myTodoList

概述 在写myList类的时候,就想到可以写一个类似的Todo清单类。 基础思路 本质还是在内部维护一个数组,在其基础上进行增删改查操作的封装为了方便存储数据,编写一个自定义内置类TodoItem,内部数组就变成了Array[TodoItem]类型的…

【Flutter】GetX

前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章,很详细 ,pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器,运用GetX去管理它 构建界面 构建一个计算器界面 …

GateWay具体的使用之全链路跟踪TraceId日志

1.创建全局过滤器,在请求头上带入traceId参数,穿透到下游服务. package com.by.filter;import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.jwt.JWTValidator;…

数据结构1(初):时间复杂度和空间复杂度

目录 1、引言 1.1、什么是数据结构? 1.2、什么是算法? 1.3、如何学好数据结构和算法 ? 2、算法效率 2.1、如何衡量一个算法的好坏 2.2、算法的复杂度 3、时间复杂度 3.1、时间复杂度的概念 3.2、大O的渐进表示法 3.3、常见时间复杂…

C语言自定义类型【联合体与枚举】

文章目录 1.联合体1.1联合体的声明1.2联合体的特点1.3联合体的大小计算联合体的使用案例 2.枚举2.1枚举类型的声明2.2枚举类型的优点(为什么使用枚举)2.3枚举类型的使用 结语 1.联合体 1.1联合体的声明 和结构体一样,联合体也是由一个或多个成员构成,同…

Atcoder Beginner Contest351 A-E Solution题解

文章目录 [A - The bottom of the ninth](https://atcoder.jp/contests/abc351/tasks/abc351_a)[B - Spot the Difference ](https://atcoder.jp/contests/abc351/tasks/abc351_b)[D - Grid and Magnet](https://atcoder.jp/contests/abc351/tasks/abc351_d)E Note:…

Rust 实战练习 - 12. Axum Web 简单demo

Rust Web 历程 Rust 的异步框架tokio非他莫属,而web框架一直是悬而未决,说到底还是因为没有官方成熟的方案指引,大家各玩各的,互不兼容,白白浪费精力。 这个事情一直等到半官方组织tokio推出axum有了改善。但是市场上…

如何将本地Android studio项目上传到GitHub

操作步骤: 1、在GitHub上创建账户 2、在androd studio中添加上述创建的GitHub账号 3、在android studio上找到"share project on GitHub",点击此选项上传当前项目到GitHub 上传成功后,会在GitHub上创建默认仓库repository 注&a…