当前位置: 首页 > news >正文

linux进程控制——进程替换——exec函数接口

        前言: 本节内容进入linux进程控制板块的最后一个知识点——进程替换。 通过本板块的学习, 我们了解了进程的基本控制方法——进程创建, 进程退出, 进程终止, 进程替换。

        进程控制章节和上一节进程概念板块都是在谈进程, 也就是说, 进程的相关内容博主整整通过两个大章, 一共12篇文章进行讲解, 并且几乎每一篇的字数都达到了纯论述五千字左右, 少的也有3500字以上, 多的甚至将近破7000。由此可以看到进程非常重要以及学习难度大。 其中进程概念是一个大难点, 里面知识点多, 晦涩难懂, 博主足足讲解了9篇,并且文章很长。 而进程控制有了前面进程概念的基础, 在理解起来就相对轻松一些, 并且内容较少, 论述性文字可能少一些, 博主通过包括本篇在内的3篇文章就可以完成讲解。 总之, 进程很重要, 希望友友们耐心学习。下面, 进入本节的学习吧。

        ps:本节适合了解进程概念, 以及进程的创建, 退出, 终止和等待的友友们进行观看。

目录

 什么是进程替换

单进程的进程替换

进程替换的原理

​编辑多进程的程序替换

 程序替换有没有创建新的进程

CPU是如何获取程序的入口地址的

详解exec接口

execl

execlp

execv

exec加载器

exec执行用户写的程序——含execle讲解

putenv

execle


 什么是进程替换

linux下有一种接口可以进行进程替换工作——exec

使用man手册, 然后就可以观察到详细内容:

上面的这些接口, 他们的工作都是一样的——把一个文件(可执行程序)替换程当前进程。 

单进程的进程替换

我们先以单进程, 也就是没有创建子进程为例, 来使用一下, 试验一下进程替换函数——exec, 我们这里使用的是execl函数, 因为它是最简单的一个进程替换函数。 

execl的参数是可变参数, 最后一个参数一定是NULL。如下图:

运行结果如下:

运行后我们就发现我们自己写的程序竟然能够将系统命令封装起来进行执行——这个过程, 就叫做程序替换。 而程序替换的现象就是把别人的程序替换一下, 在执行替换函数的之前逻辑的代码会跑,但是之后逻辑的代码就不会跑了。

进程替换的原理

        程序替换我们从上面的实验就能看到, 其实就是调用一下系统里面的其他程序, 生成一个新的进程。这个新的进程会生成一个PCB。

        首先, 会生成如下图:

        然后调用ls, 那么就会又将ls的代码数据加载到物理内存, 拷贝一份PCB、虚拟地址空间和页表。 ——这是我们以前对于创建子进程的理解。 但是对于execl, execl执行的程序不会执行上面的操作。而是直接将execl里面的程序的代码替换给物理内存里面原本进程加载的位置。 ——这, 就是程序替换。 

多进程的程序替换

然后再看一下多进程的程序替换是什么样子的。 多进程的程序替换, 我们就是要创建一个子进程,然后再执行一次程序替换。 现在我们就来实验一下:

        首先, 创建一个父进程:

然后, 根据父进程, 创建, 拷贝出子进程。 

        然后程序替换子进程:

在没有运行程序前, 什么都不会打印。

开始运行程序后, 父子进程都会被打印。 

5秒后子进程被替换, 执行ls。 同时执行完毕被等待, 资源被回收, 我们就能看到只会打印父进程了!!

 程序替换有没有创建新的进程

        刚开始运行的时候, 父子进程的PID一直没有变。 我们知道, 创建新进程需要创建新的PCB和地址空间以及页表。 然后拷贝所有的数据, 当涉及物理内存的修改时发生写时拷贝。 而父子进程的PID没有变, 也就是说, 程序替换不创建新进程, 只进行进程的代码和数据的替换工作!!

        那么, 为什么execl之后的代码没有被执行呢? 因为对于execl之后的代码来说, 这些代码的本质上也是属于原本的进程的。 但是当这个execl被执行, 这个进程的代码和数据就被替换了。 原本的代码和数据当然就没有用了!!

CPU是如何获取程序的入口地址的

        我们的CPU是如何获取程序的入口地址的呢? 这是因为, linux中形成的可执行程序, 是有格式的——ELF。 也就是可执行程序的表头, 这个表描述了可执行程序的段, 比如代码段, 数据段等等。 同时也有一个可执行程序的入口地址。 

详解exec接口

        现在重新看一下这些exec接口

execl

现在看博主写的这个程序:

        上面的程序调用了execl。 首先我们思考一下, 执行一个程序的第一件事是什么? 是不是要找到这个程序?所以, execl函数里面的第一个参数就是一个路径,是我们要执行的程序的绝对路径(相对路径也可, 但是执行命令的地方会被限制)。然后找到这个程序后, 我们是不是还要看看执行什么选项? 要以什么方式打开这个程序? 所以, 第二个参数以后的参数, 都是一些选项, 并且这些选项的最后一个必须是NULL, 就相当于一个链表。 链表里面存的是这些选项!!!为了区分表尾, 就必须把最后一个选项弄成NULL。

execlp

这个函数名比execl多了一个p, 这个p就叫做PATH路径。 代表execlp自己会在默认的PATH环境变量中查找。 ——也就是说, 我们传参时不需要传路径。 只需要传执行的文件名就行了!

就比如下图:

而之所以还要加上ls, 是因为PATH中只有路径, 没有文件名。

        PATH中的路劲, 加上ls文件名。 就能解决第一个——如何找到这个程序的问题。 

execv

        现在看一下execv, v就是数组, 第一个参数还是路径加文件名。 大师第二个参数是一个字符串指针数组。 

        这个数组就是将原本的ls -al变成ls, -a, -l。 这三个字符串分别作为字符串元素让这个指针数组指向他们。

下面是实验代码:

exec加载器

        那么, 现在问题来了。 请问ls是程序吗? 是程序, 那么是程序, ls就有main, 是不是也有命令行参数? 有了命令行参数, ls的命令行参数是从哪里来的呢? ——是从execv系统调用, 或者execl, execlp里面的参数里面获得的。 execl系列函数作为系统调用, 会把第二个参数的选项作为命令行参数传给第一个参数指向的可执行性程序。 

        在linux中, 所有进程都是别人的子进程, 在命令行当中, 所有的进程都是bash子进程。 所以, 所有进程在启动的时候, 都是使用exec系列函数启动执行的。 程序替换的本质就是将要替换的进程的数据和代码加载到内存当中。 所以, exec系列函数起到的就是加载器的效果。 

exec执行用户写的程序——含execle讲解

现在我们创建一个程序, 让我们原本的程序去调用这个程序:

ps:注意, 在c++当中的后缀可以是cpp, cxx, cc

利用makefile一次创建两个可执行程序,需要使用PHONY, 如下:

然后就会生成下面两个文件:

现在我们写一个程序调用otherExe.exe

运行后, 我们执行process-7-11.exe其实就是执行了otherExe.exe

 也可以调用脚本语言, 我们先创建一个shell脚本:

运行结果如下:

由上面两个例子我们就可以知道:语言和语言之间可以替换, 无论是我们的可执行程序, 还是脚本。 那么为什么能够跨语言调用呢?

其实所有语言运行起来, 本质上都是进程!!!

execl根本不是运行语言, 而是运行的进程, 只要是进程, 那么就可以被调用。 ——也就是说, 所有的语言, 只要最终可以变成进程, 那么最终都可以使用C/C++调用!!!

那么, 现在看一下命令行参数:我们将命令行参数传给myargv:

然后命令行参数就可以被打印出来:

我们也可以打印环境变量:

 

部分的打印结果如下:

         那么, 环境变量是什么时候给进程的呢? 环境变量也是数据, 当我们创建子进程的时候, 黄金变量就已经被子进程继承下去!!!

        所以, 我们即便没有传递命令行参数, 也是可以的!!!extern char** environ, 在进程定义的时候已经被父进程初始化了。 只要我们不写, 那么最终就是父进程的环境变量表!!!

        也就是说, 只要我们不写, 那么就是一张环境变量表。

        所以, 程序替换的时候, 环境变量的信息, 不会被替换。 所有如果我们相隔i紫禁城传递环境变量, 能怎么传递?

  • 第一种方式是新增环境变量——使用putenv在父进程中创建环境变量让子进程继承。
  • 第二种方式是彻底替换环境变量——使用execle替换

putenv

        我们先创建一个环境变量

        运行后, 我们的程序也有了这个环境变量:

        putenv的使用方法:putenv(“环境变量=数值") 在当前进程下创建一个环境变量并继承下去。

        在当前进程创建环境变量, 不会影响bash进程。

 

execle

传环境变量:带e的execl

 execle的参数如下:

 运行后就是下图: 可以看到运行结果里面也有MYNEWENV=666

 我们自定义这一张环境变量表

然后打印出来就是如下, 只会打印出我们自己定义的环境变量,  不会打印系统默认的环境变量。

自定义环境变量表, 采用的是覆盖, 而不是追加, 这就是彻底替换环境变量。

以上, 就是本届的全部内容, 下面是博主整理的本节的笔记:

相关文章:

linux进程控制——进程替换——exec函数接口

前言: 本节内容进入linux进程控制板块的最后一个知识点——进程替换。 通过本板块的学习, 我们了解了进程的基本控制方法——进程创建, 进程退出, 进程终止, 进程替换。 进程控制章节和上一节进程概念板块都是在谈进程…...

Apache解析漏洞~CVE-2017-15715漏洞分析

Apache解析漏洞 漏洞原理 # Apache HTTPD 支持一个文件拥有多个后缀,并为不同后缀执行不同的指令。比如如下配置文件: AddType text/html .html AddLanguage zh-CN .cn# 其给 .html 后缀增加了 media-type ,值为 text/html ;给 …...

Xilinx管脚验证流程及常见问题

1 流程 1.1 新建I/O Planning Project I/O Planning Project中可以不需要RTL的top层.v代码,仅图形化界面即可配置管脚约束XDC文件的生成: Create I/O Ports: 导出XDC文件和自动生成的top_interface.v文件: 1.2 新建test Project …...

格雷厄姆的《聪明的投资者》被誉为“投资圣经”

本杰明格雷厄姆的《聪明的投资者》(The Intelligent Investor: A Book of Practical Counsel)是投资领域的一部经典之作,被誉为“投资圣经”。以下是对该书的详细解析: 一、书籍基本信息 书名:《聪明的投资者》&…...

TypeScript声明文件

TypeScript声明文件 在JavaScript的生态系统中,随着项目的复杂度和规模不断增加,开发者对于类型安全和代码质量的追求也日益增长。TypeScript,作为JavaScript的一个超集,通过添加静态类型检查和ES6等新特性支持,极大地…...

.NET_WPF_使用Livecharts数据绑定图表

相关概念 LiveCharts 是一个开源的图表库,适用于多种 .NET 平台,包括 WPF、UWP、WinForms 等。LiveCharts 通过数据绑定与 MVVM 模式兼容,使得视图模型可以直接控制图表的显示,无需直接操作 UI 元素。这使得代码更加模块化&#x…...

一句JS代码,实现随机颜色的生成

今天我们只用 一句JS代码,实现随机颜色的生成,首先看一下效果: 每次刷新浏览器背景颜色都不一样 实现此效果的JS函数 : let randomColor () > ...: 定义一个箭头函数randomColor,用于生成一个随机颜色。 Math.ra…...

校园抢课助手【7】-抢课接口限流

在上一节中,该接口已经接受过风控的处理,过滤掉了机器人脚本请求,剩下都是人为的下单请求。为了防止用户短时间内高频率点击抢课链接,海量请求造成服务器过载,这里使用接口限流算法。 先介绍下几种常用的接口限流策略…...

char类型和int类型

一、char类型 在Java中,char(字符)类型用于表示单个字符,它是基本数据类型之一。以下是关于Java中char类型的一些重要信息: 表示方式: char类型用于存储Unicode字符,占用16位(即2个字…...

C++参悟:stl中的比较最大最小操作

stl中的比较最大最小操作 一、概述二、最小值1. min2. min_element 三、最大值1. max2. max_element 四、混合1. minmax2. minmax_element 一、概述 记录这里C11中常用的最小值和最大值的比较函数,最好的参考资料其实就是 https://zh.cppreference.com 最重要的查…...

JAVA读取netCdf文件并绘制热力图

读取netCdf的依赖 <dependency><groupId>ucar</groupId><artifactId>netcdfAll</artifactId><version>5.5.3</version><scope>system</scope><exclusions><exclusion><groupId>org.slf4j</groupId…...

数据结构——八大排序

一.排序的概念和其应用 1.1排序的概念 排序&#xff1a;排列或排序是将一组数据按照一定的规则或顺序重新组织的过程&#xff0c;数据既可以被组织成递增顺序&#xff08;升序&#xff09;&#xff0c;或者递减顺序&#xff08;降序&#xff09;。稳定性&#xff1a;假定在待…...

【Unity】RPG2D龙城纷争(十九)流程与UI界面(终章)

更新日期:2024年8月1日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介一、游戏流程1.初始化流程2.开始流程3.关卡流程4.关卡结束流程5.启用所有流程二、UI界面逻辑1.开始界面2.存档界面3.关卡界面DataRegion 数据显示逻辑区域RoundRegion 回合逻辑区域RoleMenu…...

C#类和结构体的区别

1、类class是引用类型&#xff0c;多个引用类型变量的值会互相影响。存储在堆&#xff08;heap&#xff09;上 2、结构体struct是值类型&#xff0c;多个值类型变量的值不会互相影响。存储在栈&#xff08;stack&#xff09;上 类结构关键字classstruct类型引用类型值类型存储…...

【RabbitMQ】RabbitMQ持久化

一、简介 RabbitMQ的持久化机制是一种确保数据在RabbitMQ服务重启或异常情况下不会丢失的重要特性。RabbitMQ的持久化主要包括三个方面的内容&#xff1a;交换器的持久化、队列的持久化、消息的持久化。 二、交换器的持久化 1、实现方式 在RabbitMQ中&#xff0c;实现交换器…...

算法刷题笔记 Kruskal算法求最小生成树(详细算法介绍,详细注释C++代码实现)

文章目录 题目描述基本思路实现代码 题目描述 给定一个n个点m条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出impossible。 最小生成树的概念&#xff1a;给定一张边带权的无向…...

5年经验的软件测试人员,碰到这样的面试题居然会心虚......

我们这边最近的面试机会比较多&#xff0c;但是根据他们的反馈&#xff0c;结束后大部分都没音信了&#xff0c;因为现在企业面试问的非常多&#xff0c;范围非常广&#xff0c;而且开放性的问题很多&#xff0c;很多人即便面试前刷了成百上千道面试题&#xff0c;也很难碰到一…...

C#进阶-轻量级ORM框架Dapper的使用教程与原理详解

本文详细介绍了Dapper在C#中的使用方法&#xff0c;包括Dapper的基本概念、与其他持久层框架的比较、基本语法和高级语法的使用&#xff0c;并通过实例讲解了如何在项目中集成和使用Dapper。Dapper以其高效的性能和简洁的API受到开发者的青睐&#xff0c;适用于各种数据库操作需…...

Windows图形界面(GUI)-MFC-C/C++ - 编辑框(Edit Control) - CEdit

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 编辑框(Edit Control) - CEdit 基本概念 成员函数 示例代码 编辑框(Edit Control) - CEdit 基本概念 编辑框&#xff08;Edit Control&#xff09;是一个允许用户输入和编辑文本的窗…...

网络安全防御【IPsec VPN搭建】

目录 一、实验拓扑图 二、实验要求 三、实验思路 四、实验步骤&#xff1a; 修改双机热备的为主备模式&#xff1a; 2、配置交换机LSW6新增的配置&#xff1a; 3、防火墙&#xff08;FW4&#xff09;做相关的基础配置&#xff1a; 4、搭建IPsec VPN通道 &#xff08;1…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...