Linux-进程替换

进程程序替换目的

首先我们要知道,创建子进程的目的是什么?

  • 想让子进程执行父进程代码的一部分
  • 想让子进程执行一个全新的代码

我们之前所写的程序,子进程都是在执行父进程代码的一部分,而要想让子进程执行全新的代码,就需要进行进程程序替换
在这里插入图片描述


了解程序替换

先来看看进程程序替换是什么
在这里插入图片描述
上面这个父进程中fork了一个子进程,然后使用程序替换接口,替换了子进程的程序,父进程等待子进程结束,回收子进程

我们看一下程序替换的结果
在这里插入图片描述
这里我们看到子进程进行程序替换成了ls进程

此时,使用我们自己的程序同样可以实现ls -al的功能,因为子进程执行的就是ls -a -l程序。因为程序替换成功了,所以返回ls程序的退出码,如果替换失败,就会执行exit(1)。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>int main() {pid_t child_pid;if ((child_pid = fork()) == 0) { // 子进程if (execl("/bin/ls", "ls", "-a", "-l", NULL) == -1) {perror("execl");exit(1);}} else if (child_pid > 0) { // 父进程int status;waitpid(child_pid, &status, 0);if (WIFEXITED(status)) {printf("Child exited with status: %d\n", WEXITSTATUS(status));} else {printf("Child process terminated abnormally.\n");}} else {perror("fork");exit(1);}return 0;
}

程序替换的原理

在这里插入图片描述

在子进程刚创建的时候,子进程和父进程通过页表映射到物理内存中空间是同一块空间,父子进程的代码段,数据段,堆,栈等区域都同一个。
在这里插入图片描述
当子进程中执行exec*()函数的时候,会发生写时拷贝,将原本物理内存中的数据段和代码段拷贝一份,放在新的物理内存中。

将磁盘中要替换的可执行程序覆盖到新的物理内存中,并且改变子进程原本的页表映射关系。

仅程序发生了替换(数据段和代码段),子进程的PCB中的task_struct仍然不变。

而且写时拷贝不仅在数据段发生,在代码段也可以发生,写时拷贝的目的同样是为了保证进程的独立性。程序替换之后,子进程执行的代码也不再是原本父进程中的代码,而是全新的代码,比如上诉例子中的ls程序。


程序替换函数

在这里插入图片描述

第一个参数path表示要执行的程序的路径,第二个参数arg表示要执行的程序的名称,后面的参数是一系列字符串类型的参数,用于指定程序的参数。这里需要注意的是,最后一个参数必须是NULL,表示参数列表的结束。

#include <unistd.h>
#include <stdio.h>int main() 
{if (fork() == 0){ // 子进程execl("/bin/echo", "echo", "Hello", "World!", NULL);} else { // 父进程wait(NULL);}return 0;
}

在这里插入图片描述

第一个参数file表示要执行的程序的文件名(不包括路径),第二个参数arg表示要执行的程序的名称,后面的参数是一系列字符串类型的参数,用于指定程序的参数。最后一个参数必须是NULL,表示参数列表的结束。

#include <unistd.h>
#include <stdio.h>int main() 
{if (fork() == 0) { // 子进程execlp("echo", "echo", "Hello", "World!", NULL);} else { // 父进程wait(NULL);}return 0;
}

注意:
execlp 函数的第一个参数是要执行的可执行程序的路径或名称。具体取决于使用的是相对路径还是绝对路径。

如果可执行程序位于当前工作目录(当前路径)中,你可以直接提供可执行程序的名称作为第一个参数。

如果可执行程序位于其他目录中,可以提供它的绝对路径或相对路径作为第一个参数。

  • 绝对路径:完整的文件系统路径,例如 /home/user/myprogram
  • 相对路径:相对于当前工作目录的路径,例如 ./myprogram../folder/myprogram

在调用 execlp 函数时,操作系统会根据给定的路径或名称去查找可执行程序,并在新的进程中执行它。

需要注意的是,execlp 函数会在系统的 PATH 环境变量定义的路径中查找可执行程序。因此,如果提供的是可执行程序的名称而不是完整路径,操作系统会根据 PATH 环境变量去寻找该程序。


在这里插入图片描述

execle 函数与 execlp 类似,但它需要显式地指定可执行程序的路径,并允许传递环境变量。下面是 execle 函数的参数说明:
path: 可执行程序的路径。可以使用绝对路径或相对路径来指定。例如,/usr/bin/myprogram 或者 ./myprogram。
arg0, arg1, …: 命令行参数,用于传递给可执行程序。常见的约定是将第一个参数作为程序的名称。例如,myprogram。
envp: 带有环境变量的指针数组。环境变量的格式为 name=value。数组最后一个元素必须为 NULL,表示环境变量列表的结束。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {char* args[] = {"echo", "$MY_VAR", NULL};char* env[] = {"MY_VAR=my_value", NULL};execle("/bin/echo", "echo", "$MY_VAR", NULL, env); // 运行 echoprintf("Exec failed\n"); // 如果运行程序失败,这行代码将不会被执行return 0;
}

在上述代码中,我们使用 execle 来运行 echo 命令,并将 $MY_VAR 作为参数传递给它。

同时,我们将一个名为 MY_VAR 的环境变量设为 my_value,使用 env 数组将其传递给 execle。此时,当 echo 命令执行时,它将打印 $MY_VAR,而不是实际的值。但是由于我们提供了 MY_VAR=my_value 的环境变量,因此 echo 命令可以获取到 MY_VAR 的实际值,所以输出将是 my_value。

需要注意的是,execle 会替换当前进程,所以在执行成功之后,程序就不会再执行下面的代码。如果 execle 执行失败,则会继续执行下面的代码,这时我们可以根据自己的需求进行错误处理。


在这里插入图片描述

第二个参数的指针数组,和mian命令函数中的char* argv[]一样,argv[0]是程序名,argv[1]等之后的是选项,最后一个是NULL。

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

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

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

相关文章

时序预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost时间序列预测

时序预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost时间序列预测 目录 时序预测 | MATLAB实现基于BiLSTM-AdaBoost双向长短期记忆网络结合AdaBoost时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.Matlab实现BiLSTM-Adaboost…

低权限(无权限)时如何在mysql客户端控制台的大量输出中快速定位mysql死锁或慢sql

查看mysql的查看死锁的方式很多&#xff0c;但很多时候我们普通开发者的权限比较低&#xff0c;无法执行某命令。比如本次就准备使用 SHOW ENGINE INNODB STATUS;命令&#xff0c;但客户端提示权限不够。后来本人找到了另一条低权限的命令 show full PROCESSLIST;但是show fu…

MAX/MSP SDK学习07:list传递

实现自定义Obejct&#xff0c;要求将传入的一组数据100后传出。 #include "ext.h" #include "ext_obex.h" typedef struct _listTrans {t_object ob;void* outLet;t_atom* fArr;long listNum;} t_listTrans;void* listTrans_new(t_symbol* s, long arg…

常用通信接口、协议:SCCB

一、概述 SCCB(串行摄像头控制总线)是由欧姆尼图像技术公司&#xff08;OmniVision&#xff09;开发的一种类IIC的总线&#xff0c;主要用于其OV系列的图像传感器上&#xff08;但目前有很多家的图像传感器都有采用该控制总线&#xff09;。相对于IIC总线来说SCCB与之最主要的差…

阿里云服务器ECS经济型e实例优惠99元性能怎么样?

阿里云服务器ECS经济型e实例优惠99元性能怎么样&#xff1f;阿里云服务器优惠99元一年&#xff0c;配置为云服务器ECS经济型e实例&#xff0c;2核2G配置、3M固定带宽和40G ESSD Entry系统盘&#xff0c;CPU采用Intel Xeon Platinum架构处理器&#xff0c;2.5 GHz主频&#xff0…

SkyWalking配置报警推送到企业微信

1、先在企业微信群里创建一个机器人&#xff0c;复制webhook的地址&#xff1a; 2、找到SkyWalking部署位置的alarm-settings.yml文件 编辑&#xff0c;在最后面加上此段配置 &#xff01;&#xff01;&#xff01;一定格式要对&#xff0c;不然一直报警报不出来按照网上指导…

排序算法--归并排序

实现逻辑 ① 将序列每相邻两个数字进行归并操作&#xff0c;形成floor(n/2)个序列&#xff0c;排序后每个序列包含两个元素 ② 将上述序列再次归并&#xff0c;形成floor(n/4)个序列&#xff0c;每个序列包含四个元素 ③ 重复步骤②&#xff0c;直到所有元素排序完毕 void pri…

Vatee万腾的数字化掌舵:Vatee科技解决方案的全面引领

随着数字化时代的到来&#xff0c;Vatee万腾凭借其卓越的科技实力和全面的解决方案&#xff0c;成功地在数字化探索的航程中掌舵引领。 首先&#xff0c;Vatee万腾以其强大的数字化科技实力成为行业的引领者。vatee万腾不仅在人工智能、大数据分析、云计算等前沿领域取得了显著…

electron入门(一)环境搭建,实现样例

1、首先需要安装git和node&#xff0c;配置环境变量&#xff0c;确保npm和git命令可用 2、 然后安装依赖 npm install -g electronnpm install -g electron-forgenpm install -g electron-prebuilt-compile3、 创建样例工程 electron-forge init my-new-app # 我这里碰见报错…

[SIGGRAPH-23] 3D Gaussian Splatting for Real-Time Radiance Field Rendering

pdf | proj | code 本文提出一种新的3D数据表达形式3D Gaussians。每个Gaussian由以下参数组成&#xff1a;中心点位置、协方差矩阵、可见性、颜色。通过世界坐标系到相机坐标系&#xff0c;再到图像坐标系的仿射关系&#xff0c;可将3D Gaussian映射到相机坐标系&#xff0c;通…

SpringMVC(五)SpringMVC的视图

SpringMVC中的视图是View接口&#xff0c;视图的作用渲染数据&#xff0c;将模型Model中的数据展示给用户 SpringMVC视图的种类很多&#xff0c;默认有转发视图(InternalResourceView)和重定向视图(RedirectView) 当工程引入jstl的依赖&#xff0c;转发视图会自动转换为JstlV…

Impala VS Hive

Impala和Hive的关系 Impala是基于Hive的大数据实时分析查询引擎&#xff0c;直接使用Hive的元数据库Metadata,意味着impala元数据都存储在Hive的metastore中。并且impala兼容Hive的sql解析&#xff0c;实现了Hive的SQL语义的子集&#xff0c;功能还在不断的完善中。 与Hive的…