Linux——进程程序替换

进程程序替换

文章目录

  • 进程程序替换
  • 1. 进程程序替换的基本概念
  • 2. exec系列函数
    • 2.1 是否带p
      • 2.1.1 execl()
      • 2.1.2 execlp()
    • 2.2 是否带e
      • 2.2.1 execle()
    • 2.3 l或v
      • 2.3.1 execvp()
    • 2.4 返回值
  • 3. 注意点

本章思维导图:
在这里插入图片描述注:本章思维导图对应的 .xmind.png文件都已同步导入至 资源,供免费查阅

1. 进程程序替换的基本概念

在利用Linux编写代码的过程中,我们经常会用fork()函数来创建子进程,来让子进程来执行特定的功能。但是,如果我们想要让子进程来执行其他程序,要怎么做呢?这就需要利用我们今天要讲的进程程序替换

进程程序替换

  • 简单来理解,进程程序替换就是通过替换正在运行中的进程的程序,从而运行新的程序
  • 实际上,要进行进程程序替换,首先就要把新程序加载到内存中,然后通过修改原进程页表的映射关系,从而将源程序的代码和数据替换为新程序的代码和数据,这样就是实现了程序的替换

结论:

  • 进程的程序替换就是对进程的代码和数据进行替换
  • 进程程序替换并不会创建新的进程

2. exec系列函数

要利用代码来真正实现进程程序替换,就需要使用系统调用。而exec系列函数就可以帮助我们实现程序替换这一过程。

exec系列函数有以下六种:

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 execvpe(const char *file, char *const argv[], char *const envp[]);

看似有6个这么多,其实我们可以将其分为三大类

是否带p

例如execlexeclp

这二者的区别就是:不带p的就需要将新程序所在的位置传入参数path;而带p 的只需要将新程序的程序名传入file即可。

是否带e

例如execlexecle

这二者的区别就是:如果不带e,那么新程序将继承父进程的环境变量;如果带e,那么环境变量需要自己设置,并传入envp****

lv

例如execlexecv

这二者的区别就是:前者程序的参数将以参数列表的形式传入;后者程序的参数将以数组的方式传入

下面将对这三种类型举例说明

2.1 是否带p

2.1.1 execl()

int execl(const char *path, const char *arg, ...);
  • path为新程序所在的位置,即为它的绝对路径
  • arg, ...为参数列表,arg为新程序的程序名,后面的**...为执行新程序附带的选项,且必须以NULL结尾**。例如,如果我要替换为命令ls -a,那么arg, ...就应该写为:“ls”, "-a", NULL

例如:

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    //执行命令“ls -a -l”
    execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
  }

  wait(NULL);

  return 0;
}

执行结果:

在这里插入图片描述

2.1.2 execlp()

int execlp(const char *file, const char *arg, ...);
  • execl()相比,只有一点不同:其不再需要传入新程序的具体路径,而是只需要传入新程序的程序名file就可以了

例如:

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    //执行命令“ls -a -l”
    execlp("ls", "ls", "-a", "-l", NULL);
  }

  wait(NULL);

  return 0;
}

执行结果:

在这里插入图片描述

2.2 是否带e

[execl()](###2.1.1 execl())

2.2.1 execle()

int execle(const char *path, const char *arg, ..., char * const envp[]);
  • execl()唯一不同的是:如果使用execle()来进行进程程序替换,那么新程序不会继承父进程的环境变量,而是由envp设置
  • envp是一个字符串数组,其包含着新程序的环境变量,并以NULL结尾。例如,其可以写作:{"b=aaa", NULL}

例如:

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

char* const env[] = {"b=6666666", NULL};
const char* path = "/usr/bin/env";

int main()
{
  pid_t id = fork();
  if (id == 0)
  {
    execle(path, "env", NULL, env);
  }

  wait(NULL);

  return 0;
}

执行结果:

在这里插入图片描述

2.3 l或v

[execlp()](###2.1.2 execlp)

2.3.1 execvp()

int execvp(const char *file, char *const argv[]);
  • execlp()唯一的不同便是:execvp()的命令参数不是以参数列表而是以指针数组的方式传入的

例如:

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

char* const argv[] = {"ls", "-a", "-l", NULL};

int main()
{
  char* command = argv[0];
    
  pid_t id = fork();
  if (id == 0)
  {
    execvp(command, argv);
  }

  wait(NULL);

  return 0;
}

执行结果:

在这里插入图片描述

2.4 返回值

  • 如果程序替换成功,将不会返回任何结果
  • 如果程序替换失败,将返回-1

3. 注意点

一旦程序替换替换成功,那么原进程在进程替换之后的所有代码便不会再执行

例如:

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

char* const argv[] = {"ls", "-a", "-l", NULL};

int main()
{
  char* command = argv[0];
  pid_t id = fork();
  if (id == 0)
  {
    execvp(command, argv);

    printf("Hello Linux!!!\n");
  }

  wait(NULL);

  return 0;
}

执行结果:

在这里插入图片描述可见Hello Linux!!!\n并没有被打印。


本篇完

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

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

相关文章

万界星空科技注塑行业MES解决方案

注塑行业是一个具有发展潜力的行业&#xff0c;随着人们对物质生活的质量要求越来越高&#xff0c;日用品、医疗保健、汽车工业以及建筑等行业对注塑制品的需求量日益增长。注塑企业提供的多种多样的塑料产品已深入到经济生活的各个领域&#xff0c;为国家经济的各个部门包括轻…

yolov8 opencv dnn部署自己的模型

源码地址 本人使用的opencv c github代码,代码作者非本人 使用github源码结合自己导出的onnx模型推理自己的视频 推理条件 windows 10 Visual Studio 2019 Nvidia GeForce GTX 1070 opencv4.7.0 (opencv4.5.5在别的地方看到不支持yolov8的推理&#xff0c;所以只使用opencv…

四、Flask学习之JavaScript

四、Flask学习之JavaScript JavaScript&#xff0c;作为一种前端脚本语言&#xff0c;赋予网页生动的交互性和动态性。通过它&#xff0c;开发者能够操作DOM&#xff08;文档对象模型&#xff09;实现页面元素的动态改变、响应用户事件&#xff0c;并借助AJAX技术实现异步数据…

【极数系列】Flink项目入门搭建(03)

【极数系列】Flink项目入门搭建&#xff08;03&#xff09; 引言 gitee地址&#xff1a;https://gitee.com/shawsongyue/aurora.git 源码直接下载可运行&#xff0c;模块&#xff1a;aurora_flink Flink 版本&#xff1a;1.18.0 Jdk 版本&#xff1a;11 1.创建mavenx项目 2.…

基于taro搭建小程序多项目框架

前言 为什么需要这样一个框架&#xff0c;以及这个框架带来的好处是什么&#xff1f; 从字面意思上理解&#xff1a;该框架可以用来同时管理多个小程序&#xff0c;并且可以抽离公用组件或业务逻辑供各个小程序使用。当你工作中面临这种同时维护多个小程序的业务场景时&#xf…

Unity中UGUI在Mask剪裁粒子特效的实现

在Unity使用Mask是剪裁不了粒子特效的&#xff0c;之前有想过RenderTexture来实现&#xff0c;不过使用RenderTexture不适合用于很多个特效&#xff0c;因为RenderTexture依赖Camera的照射&#xff0c;如果在背包中每种道具都有不同的特效&#xff0c;那使用RenderTexture则需要…

对接钉钉机器人发送钉钉通知

实现效果 话不多说 直接上代码 static void sendMsg(String msg) {new Thread(()->{try {String content "{\"msgtype\": \"text\",\"text\": {\"content\": \"" msg "\"}}";HttpUtil.simplePos…

Unity 桥接模式(实例详解)

文章目录 示例1&#xff1a;角色与装备系统示例2&#xff1a;UI控件库示例3&#xff1a;渲染引擎模块示例4&#xff1a;AI决策树算法示例5&#xff1a;物理模拟引擎 在Unity游戏开发中&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;是一种设计模式&#xff0c;它…

kafka(一)快速入门

一、kafka&#xff08;一&#xff09;是什么&#xff1f; kafka是一个分布式、支持分区、多副本&#xff0c;基于zookeeper协调的分布式消息系统&#xff1b; 二、应用场景 日志收集&#xff1a;一个公司可以用Kafka收集各种服务的log&#xff0c;通过kafka推送到各种存储系统…

php基础学习之整型进制

不同进制的整型数据定义 在 PHP中提供了四种整型的定义方式&#xff1a;十进制定义&#xff0c;二进制定义&#xff0c;八进制定义和十六进制。 定义格式如下&#xff1a; 十进制是最基础的&#xff1a;$a 110;二进制需要在值前面加上0b&#xff1a;$a 0B1101110;&#xf…

Java线程池,看这一篇足够

目录一览 Java线程池1. Executors提供6个线程池快捷创建方式2. ThreadPoolExecutor的7大参数3. 自定义线程池 Java线程池 上一篇《Async注解的注意事项》说到Async注解要配合自定义线程池一起使用&#xff0c;这一节说下Java的线程池。 1. Executors提供6个线程池快捷创建方式…

第八篇 交叉编译华为云Iot SDK到Orangepi3B

本篇主要内容&#xff1a; 一、交叉编译华为云Iot SDK依赖1.宿主机安装交叉编译工具链&#xff08;1&#xff09;选择下载交叉编译工具链&#xff08;2&#xff09;解压、添加环境变量、重启2.交叉编译依赖库&#xff08;0&#xff09; 准备工作&#xff08;1&#xff09; 交叉…

MySQL>基础sql语句

阅读目录 1.进入数据库2.数据库操作&#xff08;增删改查用&#xff09;3.表操作(增删改查)4.语句操作(增删改查) 回到顶部 1.进入数据库 打开终端,输入&#xff1a; /usr/local/mysql/bin/mysql -uroot -p回车 输入密码&#xff1a; 回到顶部 2.数据库操作&#xff08;增…

RabbitMQ环境配置

文章目录 安装Erlang安装RabbitMQ 安装Erlang 下载地址&#xff1a;http://erlang.org/download/otp_win64_25.3.2.7.exe 安装RabbitMQ 下载地址&#xff1a;https://www.rabbitmq.com/install-windows.html 进入RabbitMQ安装目录下的sbin目录 输入以下命令启动管理功能 …

Java 设计者模式以及与Spring关系(七) 命令和迭代器模式

简介: 本文是个系列一次会出两个设计者模式作用&#xff0c;如果有关联就三个&#xff0c;除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道设计者模式有3类23种设计模式&#xff0c;标红是特别重要的设计者模式建议都会&#xff0c;而且熟读于心&#…

Django开发_17_表单类

一、介绍 为了简化前端form表单代码 二、步骤 &#xff08;一&#xff09;创建form.py 创建一个表单类 from django import formsclass RegisterForm(forms.Form):reg_name forms.CharField(max_length10, label用户名)reg_pwd forms.CharField(max_length20, label密码…

python Seq2Seq模型源码实战,超详细Encoder-Decoder模型解析实战;早期机器翻译模型源码demo

1.Seq2Seq&#xff08;Encoder-Decoder&#xff09;模型简介 Seq2Seq&#xff08;Encoder-Decoder&#xff09;模型是一种常用于序列到序列&#xff08;sequence-to-sequence&#xff09;任务的深度学习模型。它由两个主要的组件组成&#xff1a;编码器&#xff08;Encoder&am…

顶顶通呼叫中心中间件机器人压力测试配置(mod_cti基于FreeSWITCH)

介绍 顶顶通呼叫中心中间件机器人压力测试(mod_cit基于FreeSWITCH) 一、配置acl.conf 打开ccadmin-》点击配置文件-》点击acl.conf-》我这里是已经配置好了的&#xff0c;这里的192.168.31.145是我自己的内网IP&#xff0c;你们还需要自行修改 二、配置线路 打开ccadmin-&g…

社区分享|百果园选择DataEase搭档蜜蜂微搭实现企业数据应用一体化

百果园&#xff0c;全称为深圳百果园实业&#xff08;集团&#xff09;股份有限公司&#xff0c;2001年12月成立于深圳&#xff0c;2002年开出中国第一家水果专卖店。截至2022年11月&#xff0c;百果园全国门店数量超过5600家&#xff0c;遍布全国140多个城市&#xff0c;消费会…

实现单链表的增删改查

实现单链表的增删改查的功能&#xff1a;头部插入删除/尾部插入删除&#xff0c;查找&#xff0c;在指定位置之前插入数据&#xff0c;删除pos节点&#xff0c;在指定位置之后插入数据&#xff0c;删除pos之后的节点&#xff0c;销毁链表。 SListNode.h #pragma once #includ…