linux--进程程序替换

news2024/9/23 3:14:30

目录

一、什么是进程程序替换

二、原理:

三、为什么要进行程序替换

四、六种替换函数

 命名理解

(1)函数execl

(2)函数execv

 (3)execlp

 (4)execvp

 (5)execle

(6)execve


一、什么是进程程序替换

所谓进程程序替换,顾名思义,就是使用一个新的程序替换原有的程序,进程将执行新程序的代码,而不再执行原有程序的代码,前面我们已经学习了如何创建一个进程,一般情况下,进程程序替换都不会使用父进程直接进行进程程序替换,而是让父进程调用fork()函数创建一个子进程,让子进程去执行一个新的程序即可。

二、原理:

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

   从上图当中我们可以知道一个进程的出现必须先在PCB结构当中先构建自己的PCB块,有了对应的虚拟地址之后,然后虚拟地址通过页表映射的方式在物理地址当中找到位置,然后将磁盘当中的程序加载进入对应的物理地址。

三、为什么要进行程序替换

当一个父进程在创建子进程之后,父子进程的代码是共享的,子进程只能执行父进程的代码块,但是现在我们不仅要让子进程能够执行父进程的代码块,同时也要能够让子进程能够做一些父进程不能做的事情,也就是能够执行一个全新的代码(程序),这样就能实现父子进程做的事情有所差异,大大提高了办事效率,同时也使父子进程的代码彻底分离,维护进程的独立性。

目的:让子进程帮我们执行特定的任务。

四、六种替换函数

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

int execve(const char *path, char *const argv[], char *const envp[]);

我们也可以在x-shell中通过 man 命令来查看。

如上的函数:

如果调用成功,则加载新的·程序,从启动代码开始执行,不在返回。

如果调用出错,返回-1

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

  •  命名理解

        每一个函数看似十分复杂,其实,每一个不同的字母都各代表一个含义:

l (list)表示参数采用列表
v(vector)参数采用数组
p (path)有p自动搜索环境变量
e (env)表示自己维护环境变量

  •  各函数之间的关系

        

 事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve。

(1)函数execl

#include <unistd.h>

int execl(const char* path, const char* arg, ...);

返回值:失败返回-1

参数1:待替换程序的路径,比如“/usr/bin/ls” 

参数2:待替换程序的名称,比如“ls”

后面的参数:待替换程序的选项,如 -a -l等,最后一个参数为 NULL,表示选项传递结束

注意: 参数选项传递结束或不传递参数,都要在最后加上 NULL,类似于字符串的 '\0'

案例:(这里替换调用的是 ls 命令)

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main(){
  4   printf("程序替换:\n");                                                   
  5   int ret=execl("/usr/bin/ls","ls",NULL);
  6 
  7   //可以通过返回值查看是否返回成功
  8   if(ret==-1)
  9   {
 10     printf("替换失败\n");
 11   }
 12 
 13   return 0;
 14 }

运行结果:

(2)函数execv

"v"代表的是"vector" 即execv是以vector的方式传递参数的。

#include <unistd.h>

int execv(const char* path, char* const argv[]);

返回值:失败返回-1

参数1:待替换程序的路径,比如:"/usr/bin/ls"

参数2:待替换程序名及其命名构成--数组

注意:参数的最后仍需要加上NULL

 #include<stdio.h>
 #include<unistd.h>
     
     int main(){
       printf("程序替换:\n");
       char* const argv[]={"ls","-a",NULL};   //以数组传入                                 
       int ret=execv("/usr/bin/ls",argv);
     
       //可以通过返回值查看是否返回成功
      if(ret==-1)
      {
        printf("替换失败\n");
      }
    
      return 0;
    }

 (3)execlp

#include <unistd.h>

int execlp(const char* file, const char* arg, ...);

返回值:失败返回-1

参数1:待替换程序名,比如“ls”,"pwd","clear"

参数2--N:可变参数列表,命令选项

该函数进行程序替换时,不需要写path路径,因为P代表有自动搜索的功能

#include<stdio.h>
#include<unistd.h>

int main(){
  printf("程序替换:\n");
  int ret=execlp("ls","ls","-l",NULL);

  //可以通过返回值查看是否返回成功
  if(ret==-1)
  {
    printf("替换失败\n");
  }

  return 0;
}

 (4)execvp

#include <unistd.h>

int execvp(const char* file, char* const argv[]);

返回值:失败返回 -1

参数1:待替换程序名,需要位于 PATH 中

参数2:待替换程序名及其命名构成的数组

注意:如果file的路径不在PATH中,则会替换错误

#include<stdio.h>
#include<unistd.h>

int main(){
  printf("程序替换:\n");
  char* const argv[]={"ls","-a","-l",NULL};
  int ret=execvp("ls",argv);

  //可以通过返回值查看是否返回成功
  if(ret==-1)
  {
    printf("替换失败\n");
  }

  return 0;
}

 (5)execle

#include <unistd.h>

int execl(const char* path, const char* arg, ..., char* const envp[]);
 

e表示env环境变量表,可以将自定义或当前程序·中的环境和变量传给替换程序

第一个参数:待替换程序的路径,比如:"/usr/bin/ls"

第二个参数:待替换程序名及其命名构成--数组

...

最后一个参数:替换成功后,待替换程序的环境变量表,可以自定义

(6)execve

execve 是系统真正提供的程序替换函数,其他替换函数都是在调用 execve

比如:

execl 相当于将链式信息转化为 argv 表,供 execve 参数2使用
execlp 相当于在 PATH 中找到目标路径信息后,传给 execve 参数1使用
execle 的 envp 最终也是传给 execve 中的参数3

#include <unistd.h>

int execve(const char* filename, char* const argv[], char* const envp[]);

返回值:替换失败返回 -1

参数1:待替换程序的路径

参数2:待替换程序名及其参数组成的argv表

参数3:传递给待替换程序的环境变量表

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

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

相关文章

‘cnpm‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

文章目录 1.0 问题描述2.0 检查环境&#xff1a;2.0.1查看node 环境2.0.2 cnpm 要安装好 3.0 查看原因4.0 问题解决【配置环境变量】4.0.1 方式一4.0.2 方式二 5.0 测试成功 1.0 问题描述 ‘cnpm’ 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 2.0 检…

手动开发--简单的 Spring 基于注解配置的程序

目录 手动开发--简单的 Spring 基于注解配置的程序 需求说明 思路分析程序结构 2) 程序框架图 ● 应用实例 创建ComponentScan.java注解 创建WyxSpringConfig 创建WyxSpringApplicationContext 作用 注意 获取全类名的步骤 Class.forName和Class.loadClass的区别 手…

c++ 11标准模板(STL) std::vector (二)

定义于头文件 <vector> template< class T, class Allocator std::allocator<T> > class vector;(1)namespace pmr { template <class T> using vector std::vector<T, std::pmr::polymorphic_allocator<T>>; }(2)(C17…

马上五一了,带大家玩一下五子棋——C语言

五一祝福 因为这篇博文实在五一这天完成的&#xff0c;所以呢&#xff0c;在介绍五子棋之前&#xff0c;先祝各位支持小白的大佬都五一快乐&#xff01; 花了点时间下了个“五一快乐”的五子棋&#xff0c;哈哈哈哈哈哈&#xff0c;还不太熟练&#xff0c;所以写的有点丑&…

常用 Composition API【VUE3】

二、常用 Composition API 7. 计算属性与监视 7.1 computed函数 与Vue2.x中computed配置功能一致写法 <template><h1>一个人的信息</h1>姓&#xff1a;<input type"text" v-model"person.firstName"><br><br>名&a…

【ROS 开发神器 Visual Studio Code 的安装和设置】

【ROS 开发神器 Visual Studio Code 的安装和设置】 1. Visual Studio Code的安装1.1 点击deb文件下载1.2 安装VScode1.3 启动软件1.4 添加收藏夹 2. 导入工作空间2.1 熟悉Vscode基本界面2.2 添加工作空间 3. 安装简体中文语言4. 安装ROS插件5. 安装CMake插件6. 安装括号颜色插…

SpringBoot 中的加密模块

Spring Boot 是一款流行的 Java 开发框架&#xff0c;它提供了多种加密模块&#xff0c;用于保护数据的安全性。本文将介绍 Spring Boot 中的加密模块&#xff0c;包括对称加密、非对称加密和哈希加密等&#xff0c;同时还会提供相应的代码示例。 一、对称加密 对称加密是一种…

改进YOLOv8 | 即插即用篇 | 全维动态卷积 |《 OMNI-DIMENSIONAL DYNAMIC CONVOLUTION》

单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…

关于密码学的进一步答疑:SSL和TLS的区别、CA和CT的关系

《密码学&#xff1a;一文读懂常用加密技术原理及其逻辑与应用方法》一文一经发布后&#xff0c;后台收到了许多私信&#xff0c;承蒙喜爱&#xff0c;这篇文章将主要对后台收到的高频问题予以统一回应。 问题一: 在讨论加密解密的过程中&#xff0c;常常在同一语境下同时出现S…

设计模式之原型模式(深拷贝浅拷贝)

目录 1、什么是原型模式 2、前置知识&#xff08;深拷贝&浅拷贝&#xff09; 2.1 浅拷贝 2.2 深拷贝 3、代码实现 3.1 通过Object中的clone方法实现浅拷贝 3.2 通过对象流来实现深拷贝 4、原型模式总结 4.1 优缺点 4.2 使用场景 4.3 对比直接new对象有何不同 1、…

如何使用递归函数实现Excel列号转换列标

在Excel中&#xff0c;列标与列号转换是VBA开发过程中经常用到的功能&#xff0c;下面这篇博客为大家解释了多种方法。 【Excel列标与列号转换】 那么这篇博文的核心是“递归过程”&#xff0c;实现这个功能并不是必须使用递归过程&#xff0c;但是这也不失为一种实现方法&am…

【Android入门到项目实战-- 8.2】—— 使用HTTP协议访问网络

目录 一、使用HttpURLConnection 1、使用Android的HttpURLConnection步骤 1&#xff09;获取HttpURLConnection实例 2)设置HTTP请求使用的方法 3)定制HTTP请求&#xff0c;如连接超时、读取超时的毫秒数 4)调用getInputStream()方法获取返回的输入流 5)关闭HTTP连接 2、…

NXP - LPC1769与LPC1768的区别

文章目录 NXP - LPC1769与LPC1768的区别概述笔记General description验证结论END NXP - LPC1769与LPC1768的区别 概述 openpnp设备用到了冰沙主板. 冰沙主板的主控MCU用到了LPC1769, 想着研究一下. 订了OM13085UL, 遥遥无期… 买了LPC MCU的书, 里面提到了书的作者的网店, 居…

python+vue精品课程建设制作django服务网站系统

功能介绍通篇文章的撰写基础是实际的应用需要&#xff0c;然后在架构系统之前全面复习大学所修习的相关知识以及网络提供的技术应用教程&#xff0c;以视频建设制作服务的实际应用需要出发&#xff0c;架构系统来改善现视频建设制作服务工作流程繁琐等问题。不仅如此以操作者的…

kotlin在鸿蒙开发中的实践

先说一说kotlin 我们知道&#xff1a; kotlin目前是安卓首选的编程语言。 安卓逐渐抛弃java&#xff0c;拥抱kotlin这是大的趋势。 kotlin的最大优点就是与java的互操作性。 kotlin编译的产物和java一样是bytecode(不抬杠&#xff0c;本文只说面向jvm的kotlin)。 kotlin是一…

Cadence基础操作:Schematic编辑

本文转载自B站up主:_WithB&#xff0c;原文链接如下&#xff1a;https://www.bilibili.com/read/cv20414466 鼠标 左键单击 –> 选中或确定操作 按住左键 –> 选中区域内所有组件 左键双击&#xff0c;可以选择以特定操作模式和窗口类型进入对应组件的下一层一般我是ed…

Winform从入门到精通(36)—ColorDialog(史上最全)更新中

前言 当我们需要设置某个控件的颜色时,并且需要弹出一个可以选择颜色的对话框时,这时候就需要使用ColorDialog 一、属性 1、AllowFullOpen 该属性用于启用或者禁用“自定义颜色按钮”,该属性为true时,可以自定义颜色 2、AnyColor 实际测试该属性没什么作用 3、Colo…

请求与相应

从容器到Servlet 前面我们介绍了JSP的内置对象和Servlet的相关知识&#xff0c; 以及如何部署和开发一个Servlet。但是&#xff0c; 并没有详细介绍如何将Servlet与JSP结合起来使用。Web容器是JSP唯一可以识别的HTTP服务器&#xff0c; 所以必须了解Web容器如何生成请求和响应…

来上海一个月的记录、思考和感悟

作者 | gongyouliu 编辑 | gongyouliu 从4月3号早上来上海&#xff0c;到今天差不多整整一个月了&#xff0c;也是自己正式从杭州离职创业&#xff08;我更愿意称之为自由职业者&#xff0c;毕竟我没有招聘全职员工&#xff0c;有两个朋友业余时间在帮我&#xff09;的第一个月…

SAP UI5 之Bootstrap(引导)笔记二

文章目录 Setting up Visual Studio Code for UI5 development1.0 官网 Walkthrough学习-Bootstrap 引导加载1.0.1 在 index.html中新增script标签1.0.2 在webapp 下面新增index.js文件1.0.3启动UI5的服务 Setting up Visual Studio Code for UI5 development 学习链接 Setti…