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

news2024/11/18 17:52:29

目录

进程的程序替换

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.coloradmin.cn/o/1629713.html

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

相关文章

Datart 扩装下载功能之PDF和图片下载

Datart 扩装下载功能之PDF和图片下载 首先下载依赖 yum install mesa-libOSMesa-devel gnu-free-sans-fonts wqy-zenhei-fonts -y 然后下载安装chrome yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 查看chrome版本号 google…

CSS之显示覆盖内容(z-index)

前言&#xff1a; 我们有的时候&#xff0c;希望下方的内容能够显示到上方&#xff0c;达到类似于多个图层的效果&#xff0c;此时我们可以利用z-index这个属性。 介绍&#xff1b; z-index属性值是用来设置元素的堆叠顺序(元素层级)。 覆盖原则&#xff1a; <1>特殊…

Java反序列化-CC3链

前言 前面的CC1与CC6链都是通过 Runtime.exec() 进行命令执行的。当服务器的代码将 Runtime放入黑名单的时候就不能使用了。 CC3链的好处是通过动态加载类的机制实现恶意类代码执行。 版本限制 jdk8u65Commons-Collections 3.2.1 动态类加载 loadClass -> 负责加载load…

船舶空调的特殊性和标准

船用空调的特殊性 船用空调和陆用空调的区别有&#xff1a; ①海洋环境具有高盐度、高湿度的特性&#xff0c;船用空调系统应特别注意防腐和防霉&#xff1b; ②船用空调需要适应船舶在海面航行时的倾斜或摇摆&#xff1b; ③船用空调需要长期在海上运行&#xff0c;维修不易&…

unity 录制360全景渲染图

1.打开pakcageManager &#xff0c;选择packages为 unityRegisty&#xff0c;找到unityRecorder插件下载&#xff0c;点击右下角instant安装&#xff0c;如果插件列表为空&#xff0c;检查是否连接网络&#xff0c;重启Unity 2.打开录制面板 3.add recorder 选择ImageSequence …

基于canal监听MySQL binlog实现数据增量同步

一、背景 业务反馈客服消息列表查询速度慢&#xff0c;有时候甚至要差不多20秒&#xff0c;急需优化提升速度。 二、方案 引入 首先&#xff0c;体验系统&#xff0c;发现查询慢的正是消息列表查询接口。 接着去看代码的设计&#xff0c;流程比较长&#xff0c;但从代码逻…

动手学深度学习——线性回归从零实现

1. 数据集 1.1 生成数据集 要训练模型首先要准备训练数据集&#xff0c;对于线性模型 yXwb&#xff0c;定义生成数据集的函数如下&#xff1a; def synthetic_data(w, b, num_examples): #save"""生成yXwb噪声"""# 从均值为0&#xff0c;标准…

Git重修系列 ------ Git的使用和常用命令总结

一、Git的安装和配置 git安装&#xff1a; Git - Downloads git首次配置用户信息&#xff1a; $ git config --global user.name "kequan" $ git config --global user.email kequanchanqq.com $ git config --global credential store 配置 Git 以使用本地存储机…

基于自注意力机制的长短期记忆神经网络(LSTM-SelfAttention)的回归预测

提示&#xff1a;MATLAB版本需要R2023a以上 基于自注意力机制的长短期记忆神经网络&#xff08;LSTM-SelfAttention&#xff09;是一种用于时序数据预测的模型。这个模型结合了两个不同的结构&#xff0c;即长短期记忆网络&#xff08;LSTM&#xff09;和自注意力机制&#xff…

解决HttpServletRequest中的InputStream/getReader只能被读取一次的问题

一、事由 由于我们业务接口需要做签名校验&#xff0c;但因为是老系统了签名规则被放在了Body里而不是Header里面&#xff0c;但是我们不能在每个Controller层都手动去做签名校验&#xff0c;这样不是优雅的做法&#xff0c;然后我就写了一个AOP&#xff0c;在AOP中实现签名校…

Cesium.js(1):Cesium.js简介

1 前言 现有的gis开发方向较流行的是webgis开发&#xff0c;其中Cesium是一款开源的WebGIS库&#xff0c;主要用于实时地球和空间数据的可视化和分析。它提供了丰富的地图显示和数据可视化功能&#xff0c;并能实现三维可视化开发。Cesium适用于地球科学研究、军事情报分析、航…

Java编程练习之final关键字

1.final类&#xff1a;不允许任何类继承&#xff0c;并且不允许其他人对这个类进行任何改动&#xff1b; 当被某个类设置为final类时&#xff0c;类中的所有方法都被隐式的设置为final形式&#xff0c;但是final类中的成员变量既可以被定义为final形式&#xff0c;又可以被定义…

【区块链】椭圆曲线数字签名算法(ECDSA)

本文主要参考&#xff1a; 一文读懂ECDSA算法如何保护数据 椭圆曲线数字签名算法 1. ECDSA算法简介 ECDSA 是 Elliptic Curve Digital Signature Algorithm 的简称&#xff0c;主要用于对数据&#xff08;比如一个文件&#xff09;创建数字签名&#xff0c;以便于你在不破坏它…

Maven的仓库、周期和插件

优质博文&#xff1a;IT-BLOG-CN 一、简介 随着各公司的Java项目入库方式由老的Ant改为Maven后&#xff0c;相信大家对Maven已经有了个基本的熟悉。但是在实际的使用、入库过程中&#xff0c;笔者发现挺多人对Maven的一些基本知识还缺乏了解&#xff0c;因此在此处跟大家简单地…

SpringCloud系列(19)--将服务消费者Consumer注册进Consul

前言&#xff1a;在上一章节中我们把服务提供者Provider注册进了Consul&#xff0c;而本章节则是关于如何将服务消费者Consumer注册进Consul 1、再次创建一个服务提供者模块&#xff0c;命名为consumerconsul-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选…

使用CubeMx配置GD32F303系列单片机进行DMA ADC

原理图查看 查原理图可以看到GD32F103C8T6的官方开发板GD32303C-START-V1.0的PA1没有接任何东西 使用PA1作为ADC端口 CubeMX配置ADC和时钟 配置ADC通道 启用循环模式 配置此通道ADC分频 配置ADC DMA为循环模式 配置时钟 生成项目 Keil里面的配置 选择对应的GD32型号 编译…

2024全新瀚海跑道:矢量图片迅速养号游戏玩法,每天一小时,日转现200

最初我注意到这种玩法&#xff0c;是因为最近在浏览各大平台的视频时&#xff0c;我发现了一种特殊类型的账号&#xff0c;其养号成功率高达90%。这些账号发布的视频内容和数据非常夸张&#xff0c;而且制作起来非常简单&#xff0c;任何人都可以轻松上手。这些账号主要发布矢量…

堆与优先队列——练习题

1. 数据流中的第 K 大元素 代码实现&#xff1a; 思路&#xff1a;创建一个大小为 k 的小顶堆&#xff0c;堆顶元素就是第 K 大元素 typedef struct {int *__data, *data;int size;int n; } KthLargest;#define swap(a, b) { \__typeof(a) __c (a); \(a) (b); \(b) __c; \ }…

C++ 笔试练习笔记【1】:字符串中找出连续最长的数字串 OR59

文章目录 OR59 字符串中找出连续最长的数字串题目思路分析实现代码 注&#xff1a;本次练习题目出自牛客网 OR59 字符串中找出连续最长的数字串 题目思路分析 首先想到的是用双指针模拟&#xff0c;进行检索比较输出 以示例1为例&#xff1a; 1.首先i遍历str直到遍历到数字&a…

字符串类型漏洞之updatexml函数盲注

UPDATEXML 是 MySQL 数据库中的一个函数&#xff0c;它用于对 XML 文档数据进行修改和查询。然而&#xff0c;当它被不当地使用或与恶意输入结合时&#xff0c;它可能成为 SQL 注入攻击的一部分&#xff0c;从而暴露敏感信息或导致其他安全漏洞。 在 SQL 注入攻击中&#xff0…