Linux进程替换

2023-11-02

目录

进程替换

1.定义:

2.为什么要进行进程替换?

3.怎样进行进程程序替换?

4.进程替换的原理:

原理总结:

5.Linux进程替换的函数:

5.1参数:

5.2函数返回值问题:

5.3:execl函数用例

5.3.2升级案例: 

​编辑

5.3.3调用execl函数失败的案例:

5.3.5 替换自己写的.c程序案例:

5.3.5 替换自己写的.cpp程序案例:

5.4调用execlp函数案例:

5.5调用execv函数案例:

5.6调用execle函数的案例:

5.6.2execle案例2:

 execl系列函数总结:


进程替换

1.定义:

        进程替换就是让一个进程从执行文件A的代码和数据转换到执行文件B的代码和数据,也就是说原本该进程执行的文件代码和数据会被另一个文件代码和数据替换掉,一般情况下,进程程序替换都不会使用父进程直接进行进程程序替换,而是让父进程调用fork函数去创建一个子进程,让子进程去执行一个新的程序即可。

2.为什么要进行进程替换?

        我们直到一个可执行文件程序在执行的时候是父进程执行的,当文件中有多个循环while,for等代码时,父进程对其一个一个的执行就很浪费时间,若是碰上死循环就更麻烦了,所以当父进程调用fork后创建出了子进程,父子进程是同时执行程序,效率上方便很多。

        现在需求增加了,不仅要让子进程能够执行父进程的代码块,也要让子进程能够做一些父进程不能做的事情——即执行一个全新的代码程序,这样父子进程做的事情就有所差异,使得父子进程的代码彻底分离,维护了进程的独立性。

        进程替换在生活中的例子:当我们在网上做一些OJ编程题的时候(例如牛客网,leetcode等官网),我们写好的答案提交时,都会被传入到后台中,这时系统就会创建出子进程,让该子进程执行我们的代码进行检测,检测通过多少用例,有无bug/err等。

3.怎样进行进程程序替换?

在Linux中可以使用execl系列的多个函数进行进程替换。

4.进程替换的原理:

进程程序替换的原理:

假如刚开始父子进程都是执行程序my.exe,后来想让子进程执行b.exe了,此时就要进行进程程序替换,替换的过程就是先将b.exe从磁盘加载到内存,然后重新建立子进程的页表,更新子进程的页表的映射关系。(注:这里修改的是页表的物理地址而非虚拟地址,此时父子进程代码块中的虚拟地址是一样的,但是通过页表映射出的物理地址是不一样的,父子进程的代码是互不干扰的,满足了进程的独立性。——写实拷贝。

 Linux进程地址空间——下篇_     讲上面这个知识点时,需要了解进程地址空间和写实拷贝,左边这个链接中有讲到这部分知识,感兴趣的友友们可以看看。

原理总结:

        1.子进程原本执行着和父进程一样的代码和数据,我们对子进程使用进程程序替换,也就相当于是修改代码和数据,那么系统会利用写时拷贝技术将my.exe的代码和数据拷贝一份, b.exe的代码和数据被加载到内存后,my.exe的代码和数据就会被覆盖成b.exe的代码和数据然后重新映射一份新的页表给子进程(进程独立性,一个进程的修改绝不能影响另一个进程!)

        2.程序替换的本质:将指定程序的代码和数据加载到指定的位置,覆盖原来程序的数据。


5.Linux进程替换的函数:

 可变参数列表就是可以在这些拥有...的函数中,增添多个类型的参数进行传递,没有数量、类型的限制。

5.1参数:

path:   欲替换程序的路径欲
file:     替换程序的名称
arg:     命令行参数
argv[]:    命令行参数数组                                                                                                          envp[] :环境变量表


注意:exec函数的参数必须以NULL结尾

5.2函数返回值问题:

        这些函数若调用成功则加载新的程序井执行,不具有返回值。因为调用成功与否,我们从执行结果就能直接看出来,所以设置这个函数的大佬们就没有设置返回值。

5.3:execl函数用例

 运行结果:

5.3.2升级案例: 

 运行结果:

       程序在做这些替换指令的过程中,可以参照以前执行指令的形式ls -l -a ,以前在Linux中怎么传,现在在execl函数中就怎么传:execl("/usr/bin/ls","Is","-a","-I",NULL) ;  需要注意,传参完最后需要NULL结尾。

5.3.3调用execl函数失败的案例:

结果:程序仍执行原来的代码和数据。 

5.3.4多进程的execl函数调用案例:

#include<std1o.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types .h>
#include<sys/wait.h>
#include<assert.h>

int main(){
    int status=0;
    pid_t id=fork();    //子进程
    
    if(id==0){
        printf("I am sonProcess,I am sharing recourse with fatherProcess\n");

        execl("/usr/bin/ls","ls","-a","",NULL);    //进程替换
        exit(100);
        }

    //父进程
    if(id>0){
           pid_t ret=waitpid(id,&status,0):
        //ret>0表示父进程已成功回收了子进程的资源和退出状态
        //ret==0表示子进程仍在进行,没有退出
        //ret<0表示fork了进程失败

        printf("我是父进程,pid:%d ppid:%d\n",getpid(),getppid());
        if(WIFEXITED(status)!=0){
            printf("了进程是正常结束!\n");
            printf("了进程退出码为:d\n"(status>>8)&OXFF);
                                  }
        else{
            printf("子进程是异常结束!\n");
            printf("sig code:%d\n",status & OX7F);
            sleep(3);
            }
    }
        

运行结果如下: 

 结果解析:从结果的最后一行可以看出,父进程获取子进程退出信息后展现出来的子进程退出码为0,但是在上方代码中,子进程执行的是exit(100); 子进程的退出码应为100才对,为何是0?

        真正的原因就是:子进程执行了execl函数后,处于execl后面的所有代码数据都会被execl首个参数指定的文件给覆盖掉,exit(100);被覆盖掉了,然后子进程执行完execl执行的指定文件后就正常退出了,所以子进程的退出码为0

5.3.5 替换自己写的.c程序案例:

运行结果:

5.3.5 替换自己写的.cpp程序案例:

 

总结:execl函数可以替换任何类型语言(py,java,php等)的可执行程序文件。


5.4调用execlp函数案例:

        在上个多进程的案例基础下,修改execl函数即可。

        execlp与execl函数的不同在于:多了个p,p的功能在于不用告诉系统该文件的路径,只需要将文件名称写上去就行,系统会自动去磁盘中寻找。 

 


5.5调用execv函数案例:

        execv函数中,v指代vector(相当于数组),可以将所有的执行参数,放入数组中,统一传递,而不用进行使用可变参数方案。

 如上代码中,就是将ls指令及其后面的选项,全放入一个字符指针数组中,函数便会遍历这个数组的每个元素。

 运行结果:


5.6调用execle函数的案例:

 getenv函数可以用于获取环境变量中指定属性的参数!

pro_rep2.c文件: 

 pro_rep2.c文件: 

注:这是不加environ时,使用execle函数替换新程序的结果! 


5.6.2execle案例2:

 在该函数中获取环境变量中不存在的一个属性MYENV,得到的结果如下:

 

解决方法: 

采用putenv去给环境变量添加一个属性MUENV,给其赋值,这样myenv.c代码中的MYENV就不再是full了。 

运行结果: 


 execl系列函数总结:

        事实上,只有execve是真正的系统调用函数,另外其它五个函数:execl,execv,execvp,execle,execlp的底层代码最终都是复用 execve构成,说白了就是这五个函数都是将execve作为底层封装后形成的系统接口函数,因为我们在实践过程中总需要这种封装型的特殊函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux进程替换 的相关文章

  • 如何在Linux下生成系统范围的唯一ID

    我正在使用多进程 Linux 系统 需要生成唯一的 ID 安全性不是考虑因素 因此 ID 生成器从零开始递增就可以了 而且它只是在本地计算机内 不涉及网络 显然 实现这一点并不难 但我只是想知道是否已经提供了任何东西 最好是轻量级的 这听起
  • 针对 openpose 将 GCC 9.3.0 降级到 7 后,cuda_compile_1_ generated_batch_norm_layer.cu.o.Release.cmake 出现 CMake 错误

    你知道我该如何解决以下错误吗 这是在我使用以下命令从 GCC 9 3 0 降级到 7 后发生的 使用以前版本的 GCC 我收到此错误 CMake 不支持的 GNU 版本 不支持高于 8 的 gcc 版本 https stackoverflo
  • Linux 在崩溃时自动重新启动应用程序 - 守护进程

    我有一个运行嵌入式 Linux 的系统 它的持续运行至关重要 基本上 它是一个与传感器通信并将数据中继到数据库和 Web 客户端的过程 如果发生崩溃 如何自动重启应用程序 此外 还有多个线程进行轮询 例如套接字和 uart 通信 如何确保没
  • 如何在shell脚本中扩展相对路径

    我正在编写一个脚本来使用 bash 在 linux 2 6 上设置环境变量 因此该脚本包含如下命令 export SRC DIR export LIBPATH SRC DIR lib 问题是 当我尝试 echo LIBPATH 时 它显示
  • 尽管 EXPORT_SYMBOL 模块插入时出现“模块中的未知符号”

    我正在尝试编译并插入 r8169 realtek 以太网驱动程序 我的内核版本是 ebin sony uname r 4 2 0 rc3 custom 我的本地磁盘中有相同的完整源代码 用于安装当前的内核 当我运行时该模块编译成功make
  • 如何从子进程为父进程设置环境变量?

    如何从子进程为父进程设置环境变量 例如 我有父进程和子进程 子进程继承自父进程环境变量 TMP VARIABLE 777 如何将子进程中 TMP VARIABLE 的值更改为 999 使其值对父进程可见 因为 TMP VARIABLE 99
  • 字符串常量之前的预期标识符

    有一个这样的程序 include
  • 何时调用setsockopt?在bind()和connect()之前?

    我继承了一些 TCP 代码 调用 bind tcpSocket struct sockaddr server addr sizeof server addr 在致电之前 setsockopt tcpSocket SOL SOCKET SO
  • gai_cancel() 需要很长时间才能成功

    我正在尝试在 C 中异步查找域 原因是我希望能够有效地添加超时期限 以防系统无法查找域 我遇到了 getaddrinfo a 命令 所以我决定尝试一下 然而 在我的机器上取消任何不会成功的 dns 查找 例如没有互联网连接时 永远不会花费少
  • Linux 上共享内存的生命周期是多长

    我正在使用 ftok shmget shmat shmdt 函数在 Linux 上创建 写入和读取共享段 如果我写入一个程序中的段 然后退出 然后稍后从另一个程序中读取该段 我会惊讶地发现数据仍然存在 我预计当共享一个段的最后一个进程执行
  • 在詹金斯管道作业中将变量传递给bash脚本

    我有一个 Jenkins 管道作业 其中我使用名为 setup sh 的 bash 脚本配置我的环境 如下所示 bin bash export ARCH 1 echo architecture ARCH 在 Jenkins 管道脚本中 我使
  • 如何在每个 xargs 命令之间休眠 1 秒?

    例如 如果我执行 ps aux awk print 1 xargs I echo 我想让 shell 在每次之间休眠 1 秒echo 如何更改我的 shell 命令 您可以使用以下语法 ps aux awk print 1 xargs I
  • 如何更改解释器路径并将命令行参数传递给 Linux 上的“可执行”共享库?

    这是 可执行 共享库的最小示例 假设文件名 mini c Interpreter path is different on some systems definitely different for 32 Bit machines cons
  • python中的多服务器监控/自动重启

    我有 2 个服务器程序 必须使用 GNU Screen 启动 我想使用基于 Python 的程序来强化这些服务器 防止崩溃 该程序启动每个屏幕会话 然后监视服务器进程 如果服务器进程崩溃 我需要 python 代码来终止无关的屏幕会话并再次
  • c - 后台运行的程序的退出状态

    我有一个任务 其中我必须创建一个迷你 shell 它能够执行很多操作 包括作业控制 我设法使用 fork 和 execvp 创建新的工作 但我还想获取 execvp 运行的程序的退出代码 根据我从其他帖子中查找到的内容 我可以使用以下方法来
  • 使用vim,如何快速刷新正在处理的网页?

    我已经使用 VIM 几个星期了 同时处理各种网络语言 我真的很喜欢它 我发现必须点击或单击浏览器并刷新页面才能看到代码更改的效果 这很麻烦 更烦人的是 因为我使用的是 Virtual Box 而且我倾向于在主机系统上处理 PDF 文件 因此
  • Zip 实用程序在 Linux 中每次都给我不同的 md5sum

    当我在 Linux 中压缩 Zip 2 31 同一个文件时 每次都会得到不同的校验和 如何保持上次的 md5sum 相同 我正在使用 yum 提供的最新 zip 更新 生成的存档不仅包含压缩文件数据 还包含 额外的文件属性 如参考zip 文
  • 如何在多行而不是单行输出上打印 Linux 组名称

    我尝试过 getent group 命令 id Gn user 和一些 sed 组合 但我认为我无法实现 因此向其他程序员伸出援手 我希望能够打印此 groups abc123输出 abc123 devops 构建测试设计 预期输出 gro
  • 使用 Python for Linux 模拟按键事件

    我正在编写一个脚本来自动运行特定模型 当模型失败时 它会等待用户输入 Enter 键 我可以检测到模型何时失败 但我无法使用 python 在 Linux 上 来模拟按键事件 Windows 有 SendKeys 库来执行此操作 但我想知道
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也

随机推荐

  • 从零开始学习makefile(4)makefile中%、$@、$<、$^的作用

    目录 示例 头文件fun h main cpp fun cpp makefile 与 lt 是通配符 https www quora com What does o cpp in a Makefile mean是这样描述 的作用的 for
  • 求当前数组中,最大值减最小值等于sum的数组个数

    分析 应用双端队列 构造一个可以动态的求出当前数组最大值的容器 qmax 同上在构造一个qmin 从left right等于开始 如果当前区间的qmax qmin符合条件 right向右扩充 当不符合条件时 计算上一步符合条件的所有子数组个
  • SpringBoot+SpringSecurity+Freemarker页面中使用security标签

    SpringBoot SpringSecurity Freemarker项目中在页面上使用security标签控制按钮显示隐藏达到对按钮级权限控制还是比较方便的 如下配置即可 1 引入依赖
  • 【解决】git(1)获取key——git@github.com permission denied (publickey). fatal could not read from remote repo

    Github 拒绝连接 其原因有两个 这是你的私人仓库 repo Github 不信任你的计算机 因为它没有你计算机的公钥 public key 克隆是出现 解决 先看有没有ssh 一般是子这里 C Users xxxx ssh 如果没有打
  • Kafka偏移量(Offset)管理

    1 定义 Kafka中的每个partition都由一系列有序的 不可变的消息组成 这些消息被连续的追加到partition中 partition中的每个消息都有一个连续的序号 用于partition唯一标识一条消息 Offset记录着下一条
  • 【微信小程序】-- 配置uni-app的开发环境(四十八)

    所属专栏 微信小程序开发教程 作 者 我是夜阑的狗 个人简介 一个正在努力学技术的CV工程师 专注基础和实战分享 欢迎咨询 欢迎大家 这里是CSDN 我总结知识的地方 喜欢的话请三连 有问题请私信 文章目录 前言 一 配置uni app的开
  • Android 开发中让BUTTON变漂亮的小技巧

    最近在做android前端的时候 发现系统提供的button实在太过不忍直视 于是搜索了很多其他button的做法 自己也尝试了很多 但是一个一个去查有些麻烦 索性全部记下来 下面介绍几个好用的button设定 android layout
  • 【Yapi】Window10 超详细安装 Yapi 教程

    目录 问题一 Error getaddrinfo ENOTFOUND yapi demo qunar com yapi demo qunar com 80 错误处理 问题二 Npm 安装 Yapi 的时候 想指定安装目录 结果一直提示 EP
  • warning: ISO C++ forbids converting a string constant to 'char*'

    warning ISO C forbids converting a string constant to char Wwrite strings 解决办法 int main int argc char argv char str 先把C
  • sql 时间计算

    兩個時間之差的合計 DECLARE I INT SET I DATEDIFF ms GETDATE RAND 24 GETDATE SELECT convert varchar 10 I 86400000 Days convert varc
  • QT on Android的rtsp播放器demo

    手机 平板
  • 文件导入之Validation校验List对象数组

    背景 我们的接口是一个List对象 对象里面的数据基本都有一些基础数据校验的注解 我们怎么样才能校验这些基础规则呢 我们在导入excel文件进行数据录入的时候 数据录入也有基础的校验规则 这个时候我们又该如何少写代码让Validation框
  • rtthread空闲线程与定时器

    rtthread为什么要用到空闲线程 RT Thread是一个实时操作系统 它的内核采用了基于线程的设计思路 在RT Thread中 空闲线程是一种特殊的线程 它在系统没有其他任务需要执行时会被调度执行 因此 空闲线程的存在可以利用CPU的
  • 动态规划总结

    感谢赵剑波大牛的原稿 转载于http blog sina com cn zhaojianbo0124 第一节 动态规划基本概念一 动态规划三要素 阶段 状态 决策 他们的概念到处都是 我就不多说了 我只说说我对他们的理解 如果把动态规划的求
  • open3d显示RGBD点云(rope3d数据集)

    rope3d中同时有深度图 因此 可以创建rgbd图像点云 借助open3d库 需要确定相机内参和外参 注意统一坐标系 例如都显示在world坐标系 usr bin env python3 coding utf 8 for reading
  • 【六】Python全栈之路--for循环

    文章目录 1 双向循环的练习 2 break pass continue的使用 3 for循环 4 小练习 1 双向循环的练习 1 用两个循环完成十行十列的小星星 j 0 while j lt 10 打印星星 i 0 while i lt
  • [MAE]Masked Autoencoders掩膜自编码器

    目录 非对称的编码 解码架构 方法 流程 编码器 解码器 Partial Fine tuning 图像MAE MixMIM Uniform Masking HiViT 视频MAE VideoMAE 多模态MAE M3AE https git
  • v-model支input父子组件传值

    v model用于表单数据的双向绑定 其实它就是一个语法糖 这个背后就做了两个操作 v bind绑定一个value属性 v on指令给当前元素绑定input事件 自定义组件使用v model 应该有以下操作 接收一个value prop 触
  • 线程获取锁的顺序java_多线程(五) java的线程锁

    在多线程中 每个线程的执行顺序 是无法预测不可控制的 那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性 那么如何控制 每个线程对于数据的读写顺序呢 这里就涉及到线程锁 什么是线程锁 使用锁的目的是什么 先看一个例子
  • Linux进程替换

    目录 进程替换 1 定义 2 为什么要进行进程替换 3 怎样进行进程程序替换 4 进程替换的原理 原理总结 5 Linux进程替换的函数 5 1参数 5 2函数返回值问题 5 3 execl函数用例 5 3 2升级案例 编辑 5 3 3调用