【Linux】进程(9):进程控制3(进程程序替换)

news2024/11/15 10:58:23

大家好,我是苏貝,本篇博客带大家了解Linux进程(9)进程控制1,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • (A)什么是进程程序替换
  • (B)原理
  • (C)父子进程中子进程程序替换原理
  • (D)使用所有的替换方法exec*,并且认识函数参数的含义
    • 1. execl
    • 2. execv
    • 3. execvp
    • 4. execlp
    • 5. 替换自己写的程序
    • 6. execvpe

(A)什么是进程程序替换

先直接看代码和现象,execl函数先不用管,后面会说到
在这里插入图片描述
在这里插入图片描述

通过结果我们发现,进程在执行完第一个printf函数后,执行的是ls -a -l的命令,而且不再执行第二个printf函数。所以,我们可以看出,execl函数的作用是让进程通过execl函数,执行新的程序。还是不理解,现在让我们来了解进程程序替换的原理

(B)原理

在这里插入图片描述

我们自己的代码编译后生成可执行程序,运行程序就变成了进程,此时操作系统就要为进程创建pcb、地址空间、页表,建立各种映射关系。运行程序testexec时,要将对应的代码和数据加载到内存中。

现在执行execl函数,我们知道,进程=内核数据结构+代码和数据,execl函数做的就是将本进程的代码和数据用新进程的代码和数据覆盖,进程的内核数据结构大体不变,只有少部分属性会发生改变。
在这里插入图片描述

站在替换进程的角度,就是这个进程被加载到内存中了

execl函数有没有创建新的进程?
没有,它只是用老进程的壳子执行新进程的代码

回到上面的例子,为什么没有打印第二个printf函数?
因为execl函数将本进程的代码和数据用新进程的代码和数据覆盖了

我们来看一下execl函数,我们上面的代码里面有后面的参数,但是没有用变量接收execl函数的返回值,那返回值重要吗?
不重要,我们可以不关心。只要替换成功,原来的代码就被覆盖了,所以我们不会再执行原先代码。但如果替换失败,我们还是会执行原先代码。

在这里插入图片描述

(C)父子进程中子进程程序替换原理

创建子进程,子进程可完成2种任务:

  1. 子进程执行父进程代码的一部分(即执行fork之后父子进程共享的代码)
  2. 子进程执行一个全新的程序(使用进程程序替换)

下面来讲父子进程中子进程程序替换的原理

在创建子进程后,父子进程页表映射的是同一块数据和代码空间
在这里插入图片描述

子进程要进程程序替换,对于数据a,因为进程程序替换是需要将进程的代码和数据用新进程的代码和数据覆盖,所以相当于要对数据进行写入,为了保证进程的独立性,会发生写时拷贝,即在物理内存中开辟一块新的空间,将数据a拷贝到该空间,再对该空间的数据进行写入(用新进程的数据覆盖),子进程的页表映射到该空间

那代码呢?我们之前讲的都是父子进程的代码共享,那现在呢?
因为子进程的代码也会被替换,所以也会发生写时拷贝

在这里插入图片描述

现在来用代码试一试
在这里插入图片描述

子进程执行的确实是ls -a -l命令,我们上面说过,只要替换成功,原来的代码就被覆盖了,所以我们不会再执行exit函数,所以退出码是0。
在这里插入图片描述

现在我们让进程程序替换失败,只修改了框框里的内容
在这里插入图片描述

替换失败,我们还是会执行原先代码exit(2),所以退出码是2
在这里插入图片描述

(D)使用所有的替换方法exec*,并且认识函数参数的含义

一共有6种替换方法,下面来逐一介绍
在这里插入图片描述

1. execl

exec后面的l:列表
在这里插入图片描述

第一个参数path:我们要执行的程序的路径(怎么找到程序,你得告诉我)
后面的参数:在命令行中怎么执行,就怎么传参
最后的参数:一定是NULL

举例:修改.c文件,如果我们想执行ls -l,先传ls的路径/usr/bin/ls,再传我们想怎么执行:在命令行中是ls -l,变成execl函数的参数时,就直接填上去就是了,不过它们要分成2个参数。如果我们想执行的是ls -a -l,那么就要分成3个参数(”ls”,”-a”和”-l”)

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

2. execv

v:表示数组
在这里插入图片描述

第一个参数和execl函数一样,都是要执行的程序的路径(怎么找到程序,你得告诉我)
第二个参数是个char* const类型的数组,只需要将execl除第一个参数以外的所有参数(包括NULL)放入一个数组中,再传这个数组即可

在这里插入图片描述

在这里插入图片描述

3. execvp

v:需要数组
p:查找这个程序,系统会自动在环境变量PATH中进行查找。所以用户可以不传要执行的程序的路径(但是程序名要传),直接告诉exec*函数,我要执行谁就行

在这里插入图片描述

在这里插入图片描述

4. execlp

l:list,列表
p:查找这个程序,系统会自动在环境变量PATH中进行查找。所以用户可以不传要执行的程序的路径(但是程序名要传),直接告诉exec*函数,我要执行谁就行
在这里插入图片描述

虽然有2个“top”,但它们的含义不同。第一个表示我要执行的程序的程序名,第二个是我要怎么执行该程序

5. 替换自己写的程序

我们上面替换的都是系统命令,可不可以替换我们自己写的程序呢?当然可以

先写要替换的我们自己写的程序的.c文件

在这里插入图片描述

修改要被替换的.c文件
在这里插入图片描述

execl函数的第一个参数传./myprocess我能理解,就是传要执行的程序的路径。那第二个参数不是说命令行中怎么传,我们就怎么传吗?为什么不是和命令行一样,传./myprocess,而是直接传myprocess?因为我们已经知道了myprocess的路径,命令行中传./myprocess是因为我们不知道myprocess的路径

只用make将2个.c文件都编译形成可执行程序

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

替换成功

在这里插入图片描述

6. execvpe

v:数组
p:查找这个程序,系统会自动在环境变量PATH中进行查找。所以用户可以不传要执行的程序的路径(但是程序名要传),直接告诉exec*函数,我要执行谁就行
e:环境变量

在这里插入图片描述

修改被替换进程对应的.c文件
在这里插入图片描述

第一个参数按标准来是只需要输入程序名,系统会自动在环境变量PATH中进行查找。但是因为myprocess程序不在PATH内容的路径中,所以只能./myprocess。 第2和第3个参数表示我们将它们传给myprocess程序

修改要替换的我们自己写的程序的.c文件。程序接收到了execvpe函数传递的命令行参数(argv数组)和环境变量(envp数组),现在我们将这两个数组打印出来
在这里插入图片描述
在这里插入图片描述

了解了execvpe函数之后,我们就可以知道,之前我们说环境变量的时候说bash会将命令行参数表和环境变量的表交给子进程,怎么交呢?就是bash用execvpe函数,将命令行参数表和环境变量表分别作为第二个和第三个参数 传给子进程。子进程将这2张表传给它的子进程同理。

对于execvpe函数的第三个参数的作用:整体替换所有的环境变量。所以传参时有3种选择:

  1. 用自定义环境变量传参
  2. 用默认的环境变量传参
  3. 默认的环境变量稍微修改,再传参

介绍第二种,用默认的环境变量传参
需要用到environ

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

介绍第三种,默认的环境变量稍微修改,再传参

需要用到putenv函数:修改或添加一个环境变量,其实就是将修改写入环境变量表或写入一个新的变量到环境变量表中

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

在这里插入图片描述


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

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

相关文章

PLC数采网关在实际应用中有哪些效能?天拓四方

在工业自动化领域中,PLC扮演着至关重要的角色,它负责控制和监测生产线的各个环节。然而,随着工业4.0的推进和智能制造的快速发展,单纯依靠PLC进行现场控制已无法满足企业对数据集中管理、远程监控和智能分析的需求。因此&#xff…

优化爬虫体验:揭秘IP重复率过高问题解决方案

在当今信息爆炸的时代,网络中蕴藏着大量宝贵的数据,而爬虫技术成为我们提取这些数据的重要工具。然而,随着爬虫的广泛使用,IP重复率高的问题也随之而来。本篇博文将揭秘解决这一问题的关键方法——使用IP代理。 一、 IP高重复问题…

钡铼网关: 轻松实现PLC与OPC UA服务器的双向通信

在当今工业4.0的大潮下,实现不同设备、系统之间的高效通信和数据交换已大势所趋!PLC与OPC UA服务器的对接,对于打造智能工厂具有重要意义,本文将深入探讨钡铼技术的网关如何实现这一过程,为用户提供快速且低成本的解决…

lvs集群、NAT模式和DR模式

lvs集群概念 全称是linux virtual server,是在Linux的内核层面实现负载均衡的软件。 主要作用:将多个后端服务器组成一个高可用高性能的服务器集群,通过负载均衡的算法将客户端的请求分发到后端的服务器上,来实现高可用和负载均…

Python 爬虫与 Java 爬虫:相似之处、不同之处和选项

在信息时代,网络上可用的数据量巨大且不断增长。为了从这些数据中提取有用的信息,爬虫已成为一种重要的技术。Python 和 Java 都是流行的编程语言,都具有强大的爬虫功能。本文将深入探讨 Python 爬虫和 Java 爬虫之间的差异,以帮助…

aop的几种动态代理以及简单案例(1)

Sping AOP是通过动态代理模式实现的,具体有两种实现方式,一种是基于Java原生的动态代理,一种是基于cglib的动态代理。 1.jdk动态代理 1.1创建需要被代理的方法接口 public interface TargetInteface {void method1();void method2();int me…

Java语言程序设计——篇三(1)

选择结构 概述选择单分支if语句例题讲解 双分支if-else语句例题讲解 条件运算符多分支的if-else语句例题讲解 嵌套的if语句例题讲解 switch语句结构例题讲解代码演示运行结果 概述 Java中的控制结构,包括: 1、选择结构( if、if-else、switch ) 2、循环结…

【密码学】大整数分解问题和离散对数问题

公钥密码体制的主要思想是通过一种非对称性,即正向计算简单,逆向计算复杂的加密算法设计,来解决安全通信。本文介绍两种在密码学领域内最为人所熟知、应用最为广泛的数学难题——大整数分解问题与离散对数问题 一、大整数分解问题 &#xf…

通过Umijs从0到1搭建一个React项目

有一阵时间没写react了,今天通过umi搭建一个demo项目复习一下react;umi是一个可扩展的企业级前端应用框架,在react市场中还是比较火的一个框架。 Umi官方文档:Umi 介绍 (umijs.org) 一、构建项目。 1、安装包管理工具。 官方推…

使用Go编写的持续下行测速脚本,快速消耗流量且不伤硬盘

介绍 使用go语言编写的持续下行测速脚本,可用于任意平台使用,通过指定URL清单文本文件自动遍历测速,支持多线程,支持多平台 特性 轻量级,无依赖采用内存进行缓存数据,不占用磁盘(如果内存较小请使用gcd项目),最大程度减少磁盘IO,保护硬盘寿命可自定义最大下载文件…

海外路人采访:提高了广告推广的曝光率-华媒舍

在当今社交媒体和网络广告的世界中,我们经常会听到关于火爆推广的故事,但人们对其背后的机制却知之甚少。本文将通过采访七位路人的经历,揭示这些火爆推广背后的秘密,帮助读者更好地理解和应对这一现象。 路人一:微博热…

vue中el-table单元格复制功能

一、单页面中使用 1.在el-table上绑定单击事件 cell-click“copyText” 或双击事件 cell-dblclick“copyText” 注:cell-dblclick函数有四个参数,分别是row, column, cell, event; row:可看到被其操作单元格所在行的所有的数据&…

前端八股文 对事件循环的理解

对事件循环的理解 思维导图 图示 实际案例的执行过程 总结

网页UI:想让页面更加精致,我来偷偷告诉你7个细节

采用合适的配色方案: 选择一套合适的配色方案,搭配主题色和辅助色,以及不同色调的阴影和渐变效果,可以让网页UI更加丰富、有层次感。 使用合适的字体: 选择适合网页风格的字体,如清晰易读的无衬线字体&a…

typora 两边太宽,设置宽度

步骤: 查看目前使用主题类型 文件 —> 偏好设置 —> 外观 —> 打开主题文件夹 修改对应的主题:max-width

基于 TI AM62 测试 QtWayland 部署

By Toradex秦海 1). 简介 目前主流的 ARM 平台嵌入式 Linux BSP 的显示后端基本都已经从 X11 升级到了 Wayland, 而常用的 Wayland Compositor - Weston 对于 Linux 下常用的 Qt 图形界面开发框架的一些 Plugin (比如 Qt VirtualKeyboard) 的配合并不完善&#xf…

深度学习模型分布式训练

单机单卡训练 单机多卡训练 使用torch.nn.DataParallel方式,修改简单,但单进程效率慢 使用DDP方式,多进程效率高,推荐 多机多卡 模型并行 示例:

基础架构服务API:降低成本,提升业务效益

基础架构服务API的应用可以显著降低企业的成本,并提升业务效益。通过使用这些API,企业可以充分利用云计算、自动化部署和资源管理等功能,从而减少了传统基础设施所需的大量投资和维护成本。这些API还提供了弹性扩展和自动化功能,使…

Linux系统学习 —— 计算机基础(笔记篇)

一、电脑硬件 电脑硬件由输入,控制计算,输出三部分组成。 输入部分包括键鼠,读卡器(外部接口),扫描仪(打印机的扫描仪)。计算控制部分包括CPU , 内存,硬盘&…

【Unity2D 2022:NPC】制作任务系统

一、接受任务 1. 编辑NPC对话脚本: (1)创建静态布尔变量用来判断ruby是否接受到任务 public class NPCDialog : MonoBehaviour {// 创建全局变量用来判断ruby是否接到任务public static bool receiveTask false; } (2&#xff…