[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 mmtest

mmtest:mytest.cc
	g++ -o $@ $^
mytest:pra_exec.c
	gcc -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.mfbz.cn/a/890184.html

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

相关文章

几种Word Embedding技术详解

NLP 中的词嵌入是一个重要术语&#xff0c;用于以实值向量的形式表示用于文本分析的单词。这是 NLP 的一项进步&#xff0c;提高了计算机更好地理解基于文本的内容的能力。它被认为是深度学习在解决具有挑战性的自然语言处理问题方面最重要的突破之一。 在这种方法中&#xff…

有了WPF后Winform还有活路吗?

近年来&#xff0c;随着技术的不断发展&#xff0c;Windows Presentation Foundation&#xff08;WPF&#xff09;和Windows Forms&#xff08;WinForms&#xff09;这两种技术在开发桌面应用程序方面一直备受关注。虽然WPF以其强大的功能和灵活性吸引了众多开发者&#xff0c;…

快速上手C语言【上】(非常详细!!!)

目录 1. 基本数据类型 2. 变量 2.1 定义格式 和 命名规范 2.2 格式化输入和输出&#xff08;scanf 和 printf&#xff09; ​编辑 2.3 作用域和生命周期 3. 常量 4. 字符串转义字符注释 5. 操作符 5.1 双目操作符 5.1.1 算数操作符 5.1.2 移位操作符 5.1.3 位操作符…

架构设计笔记-7-系统架构设计基础知识

目录 知识要点 单选 案例分析 1.质量属性 / 管道过滤器 / 数据仓库风格 2.面向对象风格 / 控制环路风格 3.软件架构风格 / 架构风格选择 4.体系结构方案对比 5.面向对象风格 / 基于规则风格 6.解释器风格 / 管道过滤器风格 7.面向对象风格 / 解释器风格 8.软件架构复…

【宝可梦】游戏

pokemmo https://pokemmo.com/zh/ 写在最后&#xff1a;若本文章对您有帮助&#xff0c;请点个赞啦 ٩(๑•̀ω•́๑)۶

OpenCV 环境配置

首先下载opencv&#xff0c;在opencv官网进行下载。 按照上面的步骤&#xff0c;点击进去 滑至底部&#xff0c;不切换至不同页&#xff0c;选择合适的版本进行下载(Window系统选择Windows版本进行下载)。 接下来以4.1.2版本为例&#xff1a; 点击之后会进入这个页面&#xff…

linux源码安装slurm以及mung和openssl

一、源码安装munge 1、编译安装munge &#xff08;1&#xff09;下载munge地址&#xff1a;https://github.com/dun/munge/releases &#xff08;2&#xff09;解压编译安装&#xff1a; 1 2 3 4 5 6 7 8 创建/data目录 复制文件munge-0.5.15.tar.xz 到/data目录下 tar -Jx…

闭着眼学机器学习——朴素贝叶斯分类

引言&#xff1a; 在正文开始之前&#xff0c;首先给大家介绍一个不错的人工智能学习教程&#xff1a;https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程&#xff0c;感兴趣的读者可以自行查阅。 1. 算法介绍 朴素贝叶斯是一种基于贝叶斯定理…

C# 屏幕录制工具

屏幕录制工具 开发语音&#xff1a;C# vb.net 下载地址&#xff1a;https://download.csdn.net/download/polloo2012/89879996 功能&#xff1a;屏幕录制&#xff0c;声卡采集&#xff0c;麦克风采集。 屏幕录制&#xff1a;录制屏幕所有操作&#xff0c;并转换视频格式&…

uniapp-小程序开发0-1笔记大全

uniapp官网&#xff1a; https://uniapp.dcloud.net.cn/tutorial/syntax-js.html uniapp插件市场&#xff1a; https://ext.dcloud.net.cn/ uviewui类库&#xff1a; https://www.uviewui.com/ 柱状、扇形、仪表盘库&#xff1a; https://www.ucharts.cn/v2/#/ CSS样式&…

Springboot 接入 WebSocket 实战

Springboot 接入 WebSocket 实战 前言&#xff1a; WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 简单理解&#xff1a; 1&#xff0c;常见开发过程中我们知道 Http协议&#xff0c;客户端…

详解安卓和IOS的唤起APP的机制,包括第三方平台的唤起方法比如微信

网页唤起APP是一种常见的跨平台交互方式&#xff0c;它允许用户从网页直接跳转到移动应用程序。 这种技术广泛应用于各种场景&#xff0c;比如让用户在浏览器中点击链接后直接打开某个应用&#xff0c;或者从网页引导用户下载安装应用。实现这一功能主要依赖于URL Scheme、Univ…

QD1-P21-P22 CSS 基础语法、注释、使用方法

本节学习&#xff1a;CSS 基础语法和注释&#xff0c;以及如何使用CSS定义的样式。 本节视频 https://www.bilibili.com/video/BV1n64y1U7oj?p21 CSS 基本语法 CSS&#xff08;层叠样式表&#xff09;的基本语法相对简单&#xff0c;由选择器和一组包含在花括号 {}​ 中的声…

深入Postman- 自动化篇

前言 在前两篇博文《Postman使用 - 基础篇》《玩转Postman:进阶篇》中,我们介绍了 Postman 作为一款专业接口测试工具在接口测试中的主要用法以及它强大的变量、脚本功能,给测试工作人员完成接口的手工测试带来了极大的便利。其实在自动化测试上,Postman 也能进行良好的支…

【Adobe全家桶】 Adobe 全家桶 AE AU PR ME WIN MAC 各个版本

话不多说今天直接分享 Adobe 全家桶&#xff0c;2017-2024版本 包含 window版本 和MAC版本 Adobe Photoshop 2017-2023 CS5-6 mac版本下载地址 WIN版本下载地址 Adobe After Effects 2017-2024 CS5-6 WIN版本下载地址 mac版本下载地址 Adobe Media Encoder 2017-2024 WIN版…

OceanBase + DolphinScheduler,搭建分布式大数据调度平台的实践

本文整理自白鲸开源联合创始人&#xff0c;Apache DolphinScheduler PMC Chair&#xff0c;Apache Foundation Member 代立冬的演讲。主要介绍了DolphinScheduler及其架构、DolphinScheduler与OceanBase 的联合大数据方案。 DolphinScheduler是什么&#xff1f; Apache Dolphi…

AOT漫谈专题(第二篇): 如何对C# AOT轻量级APM监控

一&#xff1a;背景 1. 讲故事 上一篇我们聊到了如何调试.NET Native AOT 程序&#xff0c;这是研究一个未知领域知识的入口&#xff0c;这篇我们再来看下如何对 Native AOT 程序进行轻量级的APM监控&#xff0c;当然这里的轻量级更多的是对 AOT 中的coreclr内容的挖掘。 二…

工业物联网关-ModbusTCP

Modbus-TCP模式把网关视作Modbus从端设备&#xff0c;主端设备可以通过Modbus-TCP协议访问网关上所有终端设备。用户可以自定义多条通道&#xff0c;每条通道可以配置为TCP Server或者TCP Slave。注意&#xff0c;该模式需要指定采集通道&#xff0c;采集通道可以是串口和网口通…

linux 下 verilog 简明开发环境附简单实例

author: hjjdebug date: 2024年 10月 12日 星期六 10:34:13 CST descripton: linux 下 verilog 简明开发环境附简单实例 甲: 安装软件 1. sudo apt install iverilog 该包verilog 源代码的编译器iverilog&#xff0c;其输出是可执行的仿真文件格式vvp格式 它可以检查源代码中…

跟踪一切学习笔记2024

目录 Track-Anything 多目标跟踪分割 masa 多目标检测跟踪: omnimotion iKUN Track-Anything 交互式,选择多个要跟踪的物体,最后是分割 多目标跟踪分割 https://github.com/gaomingqi/Track-Anything masa 多目标检测跟踪: