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

news2024/9/20 16:31:49

        前言: 本节内容进入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

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

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

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

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

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

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

相关文章

智算新风向丨趋动科技获中国信通院泰尔实验室首张智算资源池化能力泰尔测评证书

近日,趋动科技“OrionX AI算力资源池化软件”经中国泰尔实验室依据《FG-Z14-0172-01智算资源池化平台测试方案》评估测试,获得智算资源池化能力泰尔测评证书,成为该领域首个完成此评价的产品。 图1.OrionX通过智算资源池化平台评测 随着AI大…

智能巡检企业级域名 SSL 证书

一、概述 SSL 证书是一种数字证书,用于在用户和服务器之间建立加密链接,确保数据传输的安全性,防止数据在传输过程中被截获或篡改。SSL 证书不仅保护了数据传输过程中的隐私和完整性,还可以帮助验证网站的身份,防止钓…

基于SpringBoot+Vue的科研管理系统(带1w+文档)

基于SpringBootVue的科研管理系统(带1w文档) 基于SpringBootVue的科研管理系统(带1w文档) 科研的管理系统设计过程中采用Java开发语言,B/S结构,采取springboot框架,并以MySql为数据库进行开发。结合以上技术,对本系统的整体、数据库、功能模块…

鸿蒙系统开发【加解密算法库框架】安全

加解密算法库框架 介绍 本示例使用ohos.security.cryptoFramework相关接口实现了对文本文件的加解密、签名验签操作。 实现场景如下: 1)软件需要加密存储本地文本文件,需要调用加解密算法库框架选择密钥文本文件,对本地文本文…

PostgreSQL11 | 触发器

本文章代码已在pgsql11.22版本上运行且通过,展示页由pgAdmin8.4版本提供 上一篇总结了原著的第十章有关pgsql的视图的用法,本篇将总结pgsql的触发器的用法。 触发器 使用触发器可以自动化完成一些在插入数据或修改数据时,某些需要同期同步的…

【vulnhub】Depth靶机

靶机安装 下载地址:https://download.vulnhub.com/depth/DepthB2R.ova 运行环境:VMware运行该虚拟机 信息收集 靶机IP发现 nmap 192.168.93.0/24 端口扫描 nmap -A 192.168.93.154 -p- 只开起了8080端口 进行目录扫描8080端口 dirsearch -u http…

学习记录(9):Prompt提示词技巧

依旧照例先感谢前辈们的慷慨分享 今天学习的是这篇文章↓ 原文:转自公主号“博金斯的AI笔记” —《4篇Prompt论文的提示词技巧, 3 个 GPTs 实例测试》 文章目录 一、提示词框架二、逻辑链(Chain of thought)三、思维树(Tree of th…

华为Atlas 500 智能小站+鸿蒙AI大算力边缘计算解决方案

Atlas 500 智能小站鸿蒙大算力解决方案 技术规格 表3-1 技术规格 项目 说明 处理器 海思Hi3559A处理器 双核ARM Cortex A731.6GHz,32KB I-Cache,64KB D-Cache /512KB L2 cache双核ARM Cortex A531.2GHz,32KB I-Cache,32KB D-C…

如何确保PLC系统安全的可靠性,这几个注意事项你需要牢记

PLC(可编程逻辑控制器)是现代工业自动化系统中的关键组成部分。在设计 PLC 系统时,安全性是至关重要的考虑因素。本文将介绍 PLC 系统设计中的一些安全注意事项,包括电源设计、接地设计、关键数字量输入输出设计和报警设计。 一.…

阿一网络安全学院之绕过CDN发现服务器真实IP

方法一: 探测次级域名 方法二: 访问文件 使用访问错误目录获得报错信息成功 方法三: 去掉 www 查询 方法四: 使用网络测绘搜索引擎查询 和方法二获得的 IP 一样 方法五: 使用外国节点查询: 用了无数…

关于使用php的mpdf插件遇到的一些问题

一.插件版本 "mpdf/mpdf": "^8.0", 二.报错&#xff1a;Undefined index: list_style_type 这个是插件无法识别 li 标签导致&#xff0c;生成pdf是加入下面代码 <style> li { list-style-type: none; list-style-image: none; list-style-positi…

HTML-03.新浪新闻-标题-样式2

1.<span>标签 <span>是一个在开发网页时大量使用的没有语义的布局标签 特点&#xff1a;一行可以显示多个&#xff08;行内组合元素&#xff09;&#xff0c;宽度和高度默认由内容撑开 2.CSS选择器 2.1 元素选择器&#xff1a;标签名{...} 元素名称{ color:red; }…

如何在 Debian 上安装运行极狐GitLab Runner?【一】

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

04-Fastjson反序列化漏洞

免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担&…

ShardingSphere实战(5)- 读写分离

上篇博客&#xff0c;我们讲了 ShardingSphere实战&#xff08;4&#xff09;- 广播表和默认数据源 &#xff0c;这篇博客&#xff0c;我们实现一下读写分离。 一、读写分离配置 # sharding-jdbc 读写分离策略 # 给数据源起别名&#xff0c;这里名称需要和下面的一致 spring.…

【C++标准模版库】vector的介绍及使用

vector 一.vector的介绍二.vector的使用1.vector 构造函数2.vector 空间增长3.vector 增删查改4.vector 迭代器的使用1.正向迭代器2.反向迭代器 5.victor 迭代器失效问题&#xff08;重点&#xff09; 三.vector不支持 流提取与流插入四.vector存储自定义类型1.存储string2.存储…

OS_操作系统的运行环境

2024.06.11:操作系统的运行环境学习笔记 第3节 操作系统的运行环境 3.1 操作系统引导3.2 操作系统内核3.2.1 内核资源管理3.2.2 内核基本功能 3.3 CPU的双重工作模式3.3.1 CPU处于用户态&#xff08;目态&#xff09;3.3.2 CPU处于内核态&#xff08;管态&#xff09; 3.4 特权…

【mars3d】创建一个全黑的地球,太空背景色随意

关键参数&#xff1a; 1.backgroundColor 2.baseColor 3.basemaps 在basemaps没有底图的时候&#xff0c;可以直接设置地球的背景色baseColor 与此同时需要注意&#xff0c;不要showSkyBox等天空盒效果&#xff0c;不然容易看不见球在哪里&#xff0c;不好操作 链接&…

一种用于用于图像超分辨率的高效退化模型

一种用于用于图像超分辨率的高效退化模型 摘要引言退化模型设计图像降质模型简化版3.1. 模糊3.2. 下采样3.3. 噪声3.4. 随机排序 实验结果结论参考文献 摘要 为了增加数原始图像的退化丰富度&#xff0c;提高超分辨率网络的泛化能力&#xff0c;本文介绍了一种更加复杂但实用的…

秒懂C++之vector(下)

目录 前言 一.vector容器的模拟实现 1.1 基本配置 1.2 reserve 扩容 1.3 push_back 尾插 1.4 insert 插入 1.5 【】运算符 1.6 拷贝构造 1.7 运算符 1.8 resize 扩容初始化 1.9 erase 删除 1.10 迭代器构造 二.例题练习 17. 电话号码的字母组合 题目解析&#x…