[Linux] Linux 进程程序替换

标题:[Linux] Linux 进程程序替换

个人主页@水墨不写bug

(图片来源于网络)

目录

O、前言

一、进程程序替换的直观现象(什么是进程程序替换?)

二、进程程序替换的原理

三、进程程序替换的函数(怎么使用进程程序替换?)

1.execl

2.execlp

3.execle

1.execv

2.execvp

3.execve

四、进程程序替换的实际应用场景(程序替换的意义?)

进程替换的常见场景:


 正文开始:

O、前言

        在之前,我们已经学习了什么是进程的创建,退出,等待,以及有关进程地址空间的问题。接下来的进程程序替换依然是属于进程控制的范畴,但是在实际应用中,是非常重要的一种技术。

        本文不直接像书本上一样,一开始就说一大堆概念,让人摸不清头脑,而是现观察进程程序替换的现象,然后再从现象中在进一步了解进程程序替换。

一、进程程序替换的直观现象(什么是进程程序替换?)

         进程程序替换有一些专门(对口)的函数,我们可以通过man手册查到其中的一个函数:

        接下来我们直接看一段代码,用一用这个函数:

#include<stdio.h>
#include<unistd.h>int main()
{printf("process begin...\n");execl("/usr/bin/ls","ls","-a","-l",NULL);printf("process end...\n");return 0;
}

         两个打印语句分别标识进程开始与结束,话不多说,直接开始运行,结果如下:

        我们惊奇的发现,执行的现象与使用ls的现象差不多!

        通过进一步观察,可以发现:

        1)在调用execl函数之前的代码(打印process begin 的语句)执行了;

        2)调用execl函数就好像使用了 “ls” 命令;

        3)调用execl函数之后的代码没有被执行。

        为什么会发生这样的情况呢?别急,这就需要深入了解调用execl函数这一动作背后到底发生了什么——于是,我们需要谈一谈进程替换的原理。

二、进程程序替换的原理

        我们知道,我们写好并编译好的文件是一个 独立的 可执行程序:

        包括我们自己写的mytest,或者是系统上已经装好的ls等指令,都是一个独立的可执行程序。  

         execl 这类函数的功能就是,把一个新的独立的可执行程序覆盖式的加载到原来的运行起来的进程中,从而实现程序替换。

        一个进程,包括内核数据结构 + 代码和数据;这里的程序替换,替换的不仅仅是数据,还要替换代码!这也就意味着原来的代码和数据就被覆盖了,于是进程会从执行execl函数这一行开始,直接执行新加载的代码和数据。原来的数据自然就丢失了:这也就解释了 执行 execl 就像执行力 ls指令 ,在最后执行结束之后并没有打印 “process end” 的原因:

        1)执行execl之后,ls的代码和数据被加载的内存中,覆盖替换了原来的代码和数据;

        2)原来的 打印   “process end” 的代码由于被覆盖而丢失,所以没有执行;

        3)最终的返回值是ls指令的返回值,而不再是原来被覆盖的进程的返回值。


三、进程程序替换的函数(怎么使用进程程序替换?)

        我们可以通过进程程序替换的函数名称来略知一二,但是在那样通过函数名称来快速记忆之前,我们还是需要先一个一个了解进程程序替换的函数们:

list(初始化列类型):

1.execl

         就像我们之前演示的那样,其实就是execl函数使用方法,接下来需要对这个函数的传参细节做一些深入理解:

参数列表:

        *pathname: 需要替换的可执行程序的位置,需要指明具体的位置,既可以使用绝对路径,也可以使用相对路径。

        (比如想要替换ls命令,ls命令本质是一个可执行程序,位于/usr/bin/ls,于是我们第一个参数需要这样传递:“/usr/bin/ls”)

        *arg: 需要替换的可执行程序的名称

        (需要替换的ls命令的名称就是ls,于是需要传递:“ls”)

         ... : 参数列表

        (类似于printf的参数列表不限制打印的参数的个数一样,我们在命令行上想要使用不同的命令,传递的参数的个数是不同的,于是通过参数列表,我们可以传递不同的参数个数,来达到正确执行不同指令的目的)

        比如下面的这一个实例就很好的体现了上述的规则:

实例一:

 makefile:        

        当我们想要一次生成多个目标文件,那么可以定义一个伪目标:all 

        在伪目标后面 + “ : ”+ “ 需要的依赖文件名称 ” 

        在下文表明生成依赖文件的依赖方法即可:

.PHONY:all
all:mytest mmtestmmtest:mytest.ccg++ -o $@ $^
mytest:pra_exec.cgcc -o $@ $^.PHONY:clean
clean:rm -r mytest mmtest

pra_exec.c:

#include<stdio.h>
#include<unistd.h>int main()
{printf("process begin...\n");execl("/usr/bin/ls","ls","-a","-l",NULL);printf("process end...\n");return 0;
}

mytest.cc

#include<iostream>
#include<unistd.h>
using namespace std;int main()
{cout<<"C++进程开始运行"<<endl;execl("./mytest","./mytest",NULL);cout<<"C++进程结束运行"<<endl;return 0;
}

        由于我们已经编写了makefile,所以只需要make,就可以生成两个可执行程序。

        运行结果:

        在进程运行的过程中,我们发现进行了两次进程程序替换:

        ./mmytest (C++程序) ---> ./mytest(C程序) ---> /usr/bin/ls (系统命令C程序)

我们可以通过观察打印信息来观察。

        到这里我们可以得出结论:

                execl可以替换任何语言的可执行程序。(包括java,python,shell脚本语言等),唯一不同的是通过execl调用的时候传递的参数不同。

接下来的介绍只给出具体函数的使用实例,不再重复介绍同样性质的参数。 

2.execlp

#include <unistd.h>
int main()
{// 带p的,可以使用环境变量PATH,无需写全路径execlp("ps", "ps", "-ef", NULL);exit(0);
}

3.execle

#include <unistd.h>
int main()
{char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};// 带e的,需要自己组装环境变量execle("ps", "ps", "-ef", NULL, envp);exit(0);
}

vector(数组类型):

1.execv

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};//带v的需要传入数组形式的参数列表 execv("/bin/ps", argv);exit(0);
}

2.execvp

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};// 带p的,可以使用环境变量PATH,无需写全路径execvp("ps", argv);exit(0);
}

3.execve

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};// 带e的,需要自己组装环境变量execve("/bin/ps", argv, envp);exit(0);
}

函数解释

        这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。

        如果调用出错则返回-1

        所以exec函数只有出错的返回值而没有成功的返回值。

命名理解

这些函数原型看起来很容易混,但只要掌握了规律就很好记。

l(list) : 表示参数采用列表

v(vector) : 参数用数组

p(path) : 有p自动搜索环境变量PATH

e(env) : 表示自己维护环境变量

 exec*函数簇函数之间的关系:

        本质上,这些exec*函数都是对execve函数的封装,为什么?

        因为execve是一个系统调用函数!!本质上底层调用的都是相同的形式调用的execve,只不过是上层的封装转换的参数传递的方式。


四、进程程序替换的实际应用场景(程序替换的意义?)

        在我们的项目中,我们的父进程一直是运行的,不能说父进程执行了想要执行ls命令,在执行了之后自己却退出了。所以,我们在一般情况下,一定不能让父进程发生程序替换,不然父进程的代码和数据被子进程替换之后,代码和数据就丢失了!        

         所以我们需要fork创建子进程,让子进程来代替父进程来执行exec*这一类的函数,让子进程来发生程序替换,让子进程的代码和数据被替换掉,这样父进程就可以保留!

进程替换的常见场景:

        用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。

        当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。

        调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。


完~

未经作者同意禁止转载 

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

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

相关文章

rpc中常用的数据格式:Protobuf 图文详解

概述 protobuf也叫protocol buffer&#xff0c;是google 的一种数据交换的格式&#xff0c;它跨语言、跨平台。可以实现多种语言文件的数据传输实现&#xff08;java、c#、c、go 和 python 等&#xff09;&#xff0c;如一个cpp程序和一个python程序的数据传输。 由于它是一种…

【AI绘画】Midjourney进阶:三分线构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;三分线构图特点使用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 【AI绘画】Midjourney进阶&a…

D35【python 接口自动化学习】- python基础之输入输出与文件操作

day35 文件合并 学习日期&#xff1a;20241012 学习目标&#xff1a;输入输出与文件操作&#xfe63;-47 如何使用python合并多个文件&#xff1f; 学习笔记&#xff1a; 合并文件需求分析 合并两个文件 代码实现 # 合并两个文件 with open(demo1.txt) as f1:file_data_1f…

Django学习笔记之Django基础学习

Django笔记 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录…

Solidity基础语法

Solidity的在线编辑器&#xff1a;https://remix.ethereum.org/ 一、合约结构 1、SPDX许可标识&#xff1a;指定代码的开源许可 2、pragma指令&#xff1a;声明Solidity版本 3、导入语句&#xff1a;引入其他合约或库 4、合约声明&#xff1a;使用contract关键字 5、状态变量&…

C#自定义特性

特性的用处 一般用来影响某一个类的个别字段或者方法 定义特性 需要将类继承Attribute 可以通过构造函数的方式影响使用特性的方法 可以通过给自定义的特性通过加AttributeUsage特性的方法进行进一步管理 AttributeUsage特性默认传三个参数 第一个参数一般用来约束此自定义…

黑马程序员 javaWeb基础学习,精细点复习【持续更新】

文章目录 WEB开发一、HTML1.html介绍 二、CSS1.CSS介绍2.CSS导入方式3.CSS选择器4.CSS属性 三、JavaScript1.介绍2.浏览器3.js的三种输出方式4.js定义变量5.js数据类型6.js运算符7.全局函数8.函数定义9.js数组对象10.js正则对象11.字符串对象12.自定义对象13.BOM浏览器对象模型…

电脑无线网wifi和有线网同时使用(内网+外网同时使用)

一、要求 我这里以无线网wifi为外网&#xff0c;有线网卡为内网为例&#xff1a; 一、基本信息 无线wifi&#xff08;外网&#xff09;&#xff1a;ip是192.168.179.235&#xff0c;网关是192.168.179.95有线网&#xff08;内网&#xff09;&#xff1a;ip是192.168.10.25&…

系统思考与业务创新工作坊

圆满结束两天的新华三《系统思考与业务创新工作坊》项目&#xff01;在这次工作坊中&#xff0c;我们不仅深入探讨了如何通过系统思维看清复杂的业务全貌&#xff0c;还一起探索了创新背后的逻辑与突破口。 系统思考不是一时的灵感&#xff0c;而是一种持久的思维模式&#xff…

折叠翼弹射无人机产品技术详解

折叠翼无人飞行器系统采用储存、运输、发射一体化设计&#xff0c;飞行器平台可以折叠入筒&#xff0c;采用筒式气体弹射方式发射&#xff0c;其搭载可见光/红外双光载荷与战斗部&#xff0c;可以对敌方中大型坦克、装甲或防御工事进行打击。产品技术详解如下&#xff1a; 一、…

无人机之视觉技术篇

一、视觉传感器的类型 摄像头&#xff1a; 最常见的视觉传感器&#xff0c;能够捕捉可见光图像和视频。 通过单目、双目或多目摄像头的组合&#xff0c;无人机能够实现立体视觉&#xff0c;从而估算距离、深度&#xff0c;并进行物体识别和追踪。 红外传感器&#xff1a; …

推荐几本编程入门书目

对于编程入门&#xff0c;推荐以下几本书籍&#xff0c;这些书籍覆盖了不同的编程语言&#xff0c;适合零基础的学习者逐步掌握编程基础&#xff1a; 1. 《Python编程快速上手——让繁琐工作自动化》 特点&#xff1a;以简单易懂的方式介绍了Python的基础知识和编程概念&#…

UE5 使用Animation Budget Allocator优化角色动画性能

Animation Budget Allocator是UE内置插件&#xff0c;通过锁定动画系统所占CPU的预算&#xff0c;在到达预算计算量时对动画进行限制与优化。 开启Animation Budget Allocator需要让蒙皮Mesh使用特定的组件&#xff0c;并进行一些编辑器设置即可开启。 1.开启Animation Budget…

智慧油田智能安全管控方案-AI助力油气田安全管控升级

在科技日新月异的今天&#xff0c;万物纵横科技凭借其前沿的智慧油田智能安全管控方案&#xff0c;正引领着油气田行业向智能化、高效化转型。该方案深度融合了AI视频智能分析与AIoT&#xff08;物联网人工智能&#xff09;技术&#xff0c;为采油场、油气场的设备运维、环境监…

记录使用appium+夜神模拟器测试多设备时selenium和appium版本不兼容带来的问题

记录使用appium夜神模拟器测试多设备时selenium和appium版本不兼容带来的问题 好不容易解决了selenium和appium的版本冲突问题&#xff08;导致&#xff1a;AttributeError: ‘NoneType’ object has no attribute to_capabilities’异常发生&#xff09; 第二天运行代码发现…

腾讯云Android 与 iOS 相关

移动端&#xff08;Android/iOS&#xff09;支持哪几种系统音量模式&#xff1f; 支持2种系统音量类型&#xff0c;即通话音量类型和媒体音量类型&#xff1a; 通话音量&#xff1a;手机专门为通话场景设计的音量类型&#xff0c;使用手机自带的回声抵消功能&#xff0c;音质…

2024免费mac苹果电脑清理垃圾软件CleanMyMac X4.15.8

对于苹果电脑用户来说&#xff0c;设备上积累的垃圾文件可能会导致存储空间变得紧张&#xff0c;影响电脑的性能和使用体验。尤其是那些经常下载和安装新应用、编辑视频或处理大量照片的用户&#xff0c;更容易感受到存储空间的压力。面对这种情况&#xff0c;寻找一种有效的苹…

【自动驾驶】控制算法(十二)横纵向综合控制 | 从理论到实战全面解析

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

MPA-SVM多变量回归预测|海洋捕食者优化算法-支持向量机|Matalb

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

R语言从多波段tif数据中逐个提取单波段数据

在遥感和地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;将多个波段存储在一个文件中可以更有效地进行数据压缩和管理&#xff0c;减少了存储空间的需求。 在R语言中&#xff0c;处理多波段栅格数据通常涉及以下步骤&#xff1a; 读取数据&#xff1a;使用raster包中…