Linux--进程替换(转载)

news2024/10/5 20:19:23

目录

0.引入

1.替换原理

2.替换函数

execl

execv

execlp

execle

execvp

execvpe

execve

3.调用自定义程序

4.exec函数解释

5.命名理解


0.引入

创建子进程的目的是什么?

就是为了让子进程帮我执行特定的任务

让子进程执行父进程的一部分代码
如果子进程想执行一个全新的程序代码呢? 那么就要使用 进程的程序替换

为什么要有程序替换?

也就是说子进程想执行一个全新的程序代码!

这份代码看似是子进程的代码,其实也是父进程的代码,只是父进程通过id的值进行判断,让子进程运行。

1.替换原理

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数 以执行另一个程序。

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

2.替换函数

其实有六种以exec开头的函数,统称exec函数:

使用man手册查看相关exec函数

execl最后的...参数,表示可变参数列表,可以给C函数传递任意的参数

execl

int execl(const char *path, const char *arg, ...);
  • path:新程序的路径和名称。

  • arg0 ~ argn:新程序的命令行参数列表,以 NULL 结尾。arg0 表示新程序的名称,arg1 ~ argn 表示新程序的各个参数。

为什么只看到了begin()... end...为什么不显示呢?

执行程序替换,新的代码和数据都被加载了,后续的代码属于老代码,直接被替换了,没机会执行了

并且程序替换是整体替换,不能局部替换!!!

ls是磁盘上的可执行程序,execl调用了ls-la

把当前的代码和数据,从execl到磁盘中进行替换

问题:进程的程序替换,有没有创建新的进程呢?

没有!!

为什么呢?很简单,因为我只是把一个新的程序加载到我们当前进程所对应的代码和数据段,我就让CPU去调度当前进程,就可以跑起来了。其中,我们并没有创建新的进程。当前的进程PID没有变化

这是站在进程的角度来看的

那么站在程序的角度呢? -- 这个程序被加载到内存里了

所以,我们也可以说execl是加载器

问题:当创建进程的时候,先加载进程数据结构,还是先加载代码和数据?

在创建进程时,操作系统通常会先创建进程数据结构,然后再加载代码和数据。

这里代码,子进程里的execl替换代码,会影响父进程吗?

不会,程序替换只会影响调用进程,进程具有独立性

子进程加载新程序的时候,是需要进行程序替换的,发生写时拷贝(子进程执行的可是全新的程序,新的代码,写时拷贝在代码区也可以发生)

execl函数调用失败,会发生什么?

我们写一个代码,让程序故意发生错误

父进程获取子进程退出码

接下来开始熟悉所有的接口

execv

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

execv() 函数接受两个参数。第一个参数是要执行的程序的路径,第二个参数是传递给新程序的命令行参数。这些参数以一个字符串数组的形式传递给函数。

注意:当execv调用失败的话,程序继续执行

execlp

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

其中,file 参数表示要执行的可执行文件的名称,arg 参数表示传递给该可执行文件的命令行参数,最后的参数为可变参数列表,表示该命令行参数以 NULL 结束。

execlp 函数会在 PATH 环境变量指定的路径中查找可执行文件,因此无需指定可执行文件的完整路径。如果 PATH 环境变量中有多个路径,则 execlp 函数会按照路径的顺序查找可执行文件。

execlp("ls","ls","-a","-l","-n",NULL);

这里的两个ls分别是什么意思?

第一个是系统环境变量路径ls,第二个是ls指令

等同于以下代码

execle

 
  1. int execle(const char *path, const char *arg,

  2. ..., char * const envp[]);

该函数接收以下参数:

  • path:要执行的程序的路径名。

  • arg0:新程序的第一个参数,通常是新程序的名称。

  • arg1~argn:新程序的参数列表。

  • envp:新程序的环境变量数组。

该函数的返回值是一个整数,如果成功执行,则永远不会返回。如果出现错误,则会返回-1,并设置errno来指示错误的类型。

envp[]数组是自定义环境变量

execvp

函数原型如下:

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

该函数会在PATH环境变量指定的路径中搜索指定的可执行文件,并在找到文件后将当前进程替换为该可执行文件。

其中,file参数是一个字符串,指定要执行的可执行文件的路径和文件名。argv参数是一个指向字符串数组的指针,其中第一个字符串表示可执行文件的名称,后面的字符串表示传递给可执行文件的命令行参数。

execvpe

函数原型如下:

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

file 参数是要执行的可执行文件的路径,argv 参数是一个指向参数列表的指针数组,envp 参数是一个指向环境变量列表的指针数组。

execvpe 函数首先会搜索 PATH 环境变量中指定的目录,找到可执行文件后,它会用新的进程替换当前进程,并开始执行新的程序。在新的进程中,参数和环境变量都被设置成 argv 和 envp 中指定的值。

execvpe 函数和其他 exec 系列函数的主要区别在于它会搜索 PATH 环境变量中指定的目录来查找可执行文件,并且可以设置环境变量。

execve

函数原型如下:

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

filename 参数是要执行的可执行文件的路径,argv 参数是一个指向参数列表的指针数组,envp 参数是一个指向环境变量列表的指针数组。

execve 函数会用新的进程替换当前进程,并开始执行新的程序。在新的进程中,参数和环境变量都被设置成 argv 和 envp 中指定的值。

execve 函数不会搜索 PATH 环境变量中指定的目录来查找可执行文件,它只会使用 filename 参数中指定的路径来查找可执行文件。如果指定的文件路径不是一个可执行文件,那么该函数会返回一个错误。

事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。下图exec函数族 一个完整的例子:

3.调用自定义程序

上面都是执行命令。能否执行我自己写的程序呢?

用C语言调用C++写的可执行程序

可以发现PID是一模一样的,替换了C++程序,没有创建新的进程

接下来尝试在C++程序中获取环境变量

获取环境变量。C++的cout如果环境变量不存在,就什么都不会打印,所以要进行判断,如果没有就打印NULL

修改下C程序,在C程序中自定义环境变量表,使用execle函数

问题:C语言调用C++可以调用到环境变量吗?

修改下C++代码,获取环境变量

C++自己写的里有PATH,但没有环境变量

观察下C语言的

C语言调用的有MYENV 但是没有PATH

调用的环境变量是覆盖式写入,会覆盖老的环境变量PATH,所以看不到PATH

传系统环境变量

C语言提供的环境变量表,二级指针,environ

此时MYENV就没有了,系统的环境变量出现了

系统环境变量和自定义环境变量同时传递

利用putenv添加到系统环境变量里,依赖头文件#include<stdlib.h>

putenv将MYENV传到系统变量里,这样调用系统变量,就可以将自定义和系统变量一块传递给替换程序

环境变量具有全局属性,可以被子进程继承下去!
就是 通过execle函数传递的环境变量!
使用export MYENV = You can see me   也可以

4.exec函数解释

1.这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
2.如果调用出错则返回-1
3.所以exec函数只有出错的返回值而没有成功的返回值。

5.命名理解

这些函数原型看起来很容易混,但只要掌握了规律就很好记。

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

exec调用举例如下:


#include <unistd.h>

int main()

{

char *const argv[] = {"ps", "-ef", NULL};

char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};

execl("/bin/ps", "ps", "-ef", NULL);

// 带p的,可以使用环境变量PATH,无需写全路径

execlp("ps", "ps", "-ef", NULL);

// 带e的,需要自己组装环境变量

execle("ps", "ps", "-ef", NULL, envp);

execv("/bin/ps", argv);


// 带p的,可以使用环境变量PATH,无需写全路径

execvp("ps", argv);

// 带e的,需要自己组装环境变量

execve("/bin/ps", argv, envp);

exit(0);

}

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

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

相关文章

深度学习——自编码器AutoEncoder

基本概念 概述 自编码器&#xff08;Autoencoder&#xff09;是一种无监督学习的神经网络模型&#xff0c;用于学习数据的低维表示。它由编码器&#xff08;Encoder&#xff09;和解码器&#xff08;Decoder&#xff09;两部分组成&#xff0c;通过将输入数据压缩到低维编码空…

小程序使用云函数调用第三方api避免域名备案

小程序使用云函数调用第三方api避免域名备案 在小程序开发中&#xff0c;如果需要调用第三方 API&#xff0c;但由于域名备案的限制无法直接在小程序中使用&#xff0c;我们可以利用云函数来解决这个问题。 1. 开通云开发 使用微信开发者工具打开小程序项目&#xff0c;点击…

IDEA 提交git 之后撤回操作

方式一 1.选择提交记录&#xff1b; 2、 右键git然后选择drop commit&#xff1b; 弊端&#xff1a;会将修改的代码全部进行删除操作 打开 IDEA 的 本地历史记录功能&#xff0c;对修改的内容进行复原 方式二&#xff1a; 1、撤回commit 2、选择项目——>右击git——…

ROS-Qt-转CMake编译以及qmake第三方库添加及其他

Qt 开发ROS 界面的方法 方法2 带ui的工作空间配置&#xff08;以ROS节点执行&#xff09; 步骤1 $ mkdir catkin_qt $ cd catkin_qt $ mkdir src $ cd src $ catkin_init_workpasce $ cd .. $ catkin_make $ cd src $ catkin_create_qt_pkg ros_ui roscpp rospy std_msgs $ …

生成式AI时代,亚马逊云科技致力推动技术的普惠,让更多企业受益

当谈及AIGC时&#xff0c; 我们该谈些什么&#xff1f; 生成式AI技术与应用的不断发展&#xff0c;为各个行业都注入了全新的机会与活力。AIGC成为了今年最为激动人心的技术话题。亚马逊云科技也一马当先&#xff0c;在6月27-28日&#xff0c;2023亚马逊云科技中国峰会上分享…

堆的Top-K问题

⭐️ TOP-K问题 TOP-K问题&#xff1a;即求数据结合中前 k k k 个最大的元素或者最小的元素&#xff0c;一般情况数据量都比较大。 比如&#xff1a;专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。 如果数据量过大&#xff0c;排序的方式就不太可取了。 思路&…

TikTok引流的新玩法,用AdsPower打开新大陆!

做跨境电商的人都知道&#xff0c;天上不会掉流量&#xff0c;想要产品火&#xff0c;就必须要引流。大佬的一个产品动不动就几千几万的观看量&#xff0c;可是自己的产品却无人问津。他们到底怎么做到的呢&#xff1f;很简单&#xff0c;注册AdsPower和TikTok的账号&#xff0…

el-input输入框的那些事

vue3element-plustses6 此帖只为记录开发中遇到的需求&#xff0c;技术问题&#xff0c;坑 1、文本域禁止自由拉伸 1、文本域禁止自由拉伸 el-input有一个枚举类型的resize属性&#xff0c;控制拉伸&#xff0c;‘none’ | ‘both’ | ‘horizontal’ | ‘vertical’&#xf…

找实拍高清视频网站,我推荐这6个

本期推荐6个高清视频素材网站&#xff0c;视频剪辑、自媒体必备&#xff0c;建议收藏~ 菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库虽然是一个设计网站&#xff0c;但它还有非常丰富的视频和音频素材&#xff0c;视频素材全部都是高清无水印&#xff0…

暑期代码每日一练Day1:Leetcode415. 字符串相加

题目 415. 字符串相加 分析 题目意思是给你两个纯数字 字符串&#xff08;表示的是一个有意义的正整数&#xff09;&#xff0c;让你算出这两个字符串表示的数字的和&#xff0c;最后返回以字符串表示的结果&#xff0c;其中的过程不能直接将初始给定的两个字符串直接转化为…

ORB+FLANN

FLANN 代表 近似最近邻的快速库。它包含针对大型数据集中的快速最近邻搜索和高维特征优化的算法集合。对于大型数据集&#xff0c;它比BFMatcher工作得更快。 对于基于 FLANN 的匹配器&#xff0c;我们需要传递两个字典&#xff0c;指定要使用的算法、相关参数等。第一个是Ind…

2024考研408-操作系统 第三章-内存管理 学习笔记

文章目录 一、内存管理基础1.1、内存的基础知识1.1.1、什么是内存&#xff1f;有何作用&#xff1f;1.1.2、进程运行的基本原理1.1.2.1、指令的工作原理1.1.2.2、理解逻辑地址与物理地址1.1.2.3、从写程序到程序运行1.1.2.4、三种链接方式&#xff08;静态、转入时动态、运行时…

openssl源码编译输出库-guidance-傻瓜式教程

目标&#xff1a; 下载openssl源码 编译输出目标版本&#xff0c;例如使用Android NDK编译输出Android使用的32位的库 1、下载源码 git clone https://github.com/openssl/openssl.git -b openssl-3.0.9 2、 请下载Linux版本的Android NDK 请下载Linux版本的Android NDK, 并完…

没看完这篇文章,别说你会用Ping

中午好&#xff0c;我的网工朋友。 网工生活里每天都和ping打交道&#xff0c;ping来ping去&#xff0c;很多人知道ping&#xff0c;却不知道怎么把ping用出更多花样出来。 今天&#xff0c;我特地给你关于ping命令的使用大全&#xff0c;在更多不同的项目场景里&#xff0c;…

解决访问127.0.0.1时,提示“127.0.0.1 拒绝了我们的连接请求”

目录 问题描述 解决方案 问题描述 我电脑是win10系统&#xff0c;刚刚在访问http://127.0.0.1时&#xff0c;浏览器显示“127.0.0.1 拒绝了我们的连接请求”&#xff0c;为何访问本机IP显示拒绝访问&#xff1f; 解决方案 1. windows徽标 I 打开设置&#xff0c;选择“应用…

3ds max高级教程:创建带有骨骼动画的机器人模型

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 然而&#xff0c;下面我们示例机器人腿的第一个版本不是很现实&#xff0c;因为它会像没有肌肉的骨骼结构一样坍塌。在第二个版本中&#xff0c;我们将添加一些机器人“肌肉”&#xff0c;第三个版本将包括…

分布式运用存储系统Ceph

一、ceph的相关知识 1.ceph介绍与简介 Ceph是一个开源的分布式存储解决方案&#xff0c;旨在提供可扩展性、高性能和强大的数据可靠性。它采用了一种分布式对象存储架构&#xff0c;能够同时提供块存储和文件存储的功能。 Ceph使用C语言开发&#xff0c;是一个开放、自我修复和…

Makefile文件编写

文章目录 格式自动检查更新效率变量模式匹配函数clean 格式 目标&#xff1a;依赖 tab 命令 自动检查更新 当有文件发生修改后&#xff0c;重新make会自动对发生修改的依赖进行编译 效率 由于在 make时会进行检查更新&#xff0c;对于有修改的依赖会重新编译&#xff0c;为…

定位理论:引领企业变革的幕后推手

在商业的海洋中&#xff0c;如何能让你的企业像一座明亮的灯塔&#xff0c;独特而引人注目?这就需要我们掌握一种强大的工具——定位理论。那么&#xff0c;定位理论究竟是什么?我们为什么要学习它?它如何能为我们的企业创造价值?今天&#xff0c;让我们一起深入探索定位理…

vue3组件引用使用的坑

今天准备用el-tabs写个页面&#xff0c;发现点击后组件怎么都显示不了&#xff0c;后来才发现是组件引用的原因 这是页面是显示的效果&#xff1a; 乍一看确实是对的。。。 但是当我点击完这三个tab后再重新点击道路管理后&#xff0c;有意思的出现了&#xff1a; one组件消失…