Linux——进程控制(三)进程程序替换

目录

前言

一、进程程序替换

二、execl

三、多进程版execl

四、exec相关函数 

1.execlp

2.execv

3.execvp

五、替换自己写的程序

六、替换其他语言程序

七、execle


前言

之前,我们学习了进程的fork创建,进程的等待,执行的代码都是父进程代码的一部分,如果我们想要子进程执行全新的代码并访问全新的数据,不和父进程共享一份代码,此时就需要用上进程程序替换

一、进程程序替换

进程程序替换顾名思义,就是将其他程序替换过来继续执行,主要是通过exec* 这类函数来帮助我们替换,直接来学这个函数。

二、execl

下面有六个函数,我们先来学习第一个——execl。他可以帮我们执行另一个程序。用法先不解释,等下直接上案例。

我们可以用系统当中的指令来进行替换,比如ls / pwd / clean等等。直接上代码,其中execl函数的第一个参数为你要替换程序的路径,第二个参数为可执行程序名,后面的参数为可变参数,就相当于命令行参数。该程序替换成了 ls -a -l 命令,空格在代码里用引号隔开,命令行怎么写,参数就怎么传,最后传NULL代表参数传递完毕。

#include<stdio.h>    
#include<unistd.h>    int main()    
{    printf("我是一个进程, pid: %d\n",getpid());    execl("/usr/bin/ls","ls","-a","-l",NULL);                printf("替换完成,pid: %d\n",getpid());    return 0;    
}    

我们执行看看效果,打印除了execl之前的printf语句,也成功替换了程序,变成了 ls -a -l,但是并没有打印替换后的printf。

这是因为程序替换,会将磁盘中被替换的程序的代码和数据覆盖到当前进程代码和数据映射到的物理内存上。原代码和数据被覆盖后,根本就看不到你的任何printf了,全是新程序的代码,因此不会打印后续内容。

包括exec函数的返回值,他只有在失败的时候才有返回值 -1 ,成功后没有也不需要返回值,根本不带理原进程的。

三、多进程版execl

通过fork,让子进程完成程序替换,父进程等待子进程,代码如下。

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{pid_t id = fork();if(id == 0){//childprintf("我是一个进程, pid: %d\n",getpid());sleep(1);execl("/usr/bin/ls","ls","-a","-l",NULL);printf("替换完成,pid: %d\n",getpid());}else{//fatherpid_t rid = waitpid(-1,NULL,0);if(rid > 0){printf("等待成功, rid: %d\n",rid);}}return 0;                                                         
}

 运行结果如图,这里我们可以看到子进程的pid为10400,父进程等待的进程id也为10400,由此得出一个结论:程序替换并不会再生成进程,而是原进程的替换。父子进程不再只是数据结构(PCB、进程地址空间、页表)上的解耦了,连代码与数据也解耦了。

四、exec相关函数 

刚刚我们学习了第一个函数 execl ,这里一共有6个函数,看起来还有点难学,实际上并不难。

1.execlp

l为list,p为path。 

比如usr/bin在path环境变量中,ls命令就在该文件夹下。

因此我们改写代码使用execlp,可以不用添加/usr/bin/ls,直接ls就可以了。代码如下,其中第一个ls代表去环境变量里面找ls,第二个ls是命令中的一部分。

运行依然可以。 

2.execv

v代表vector,不再是可变变量,而是一个char *const argv[],这是一个指针数组,char *const是指针指向不能修改。

代码修改如下 

运行没问题。

3.execvp

execlp是list与path,execvp是vector与path。

因此修改如下

至于execle与execvpe我们后面用自己写的程序讲解

五、替换自己写的程序

先写一个简单的打印程序

修改Makefile,因为要构成两个可执行程序

主程序的execl第一个参数“./mytest” ,./代表当前文件夹下。

运行结果如下,成功替换为自己写的程序 

六、替换其他语言程序

exec 函数不仅仅可以替换C/C++程序,还可以替换其他语言,如bash脚本语言,python语言等。

比如我们写了一个bash脚本

成功的打印并创建了。 

exec*叫做进程的程序替换,不管哪个语言,在系统层面上跑都是进程,系统大于一切,因此替换成其他语言的程序也没有问题。

exec*说是进程替换,其实也是一种进程加载,完成了加载器的功能。

七、execle

exelce最后一个参数传的是环境变量。

经过之前的学习,我们知道环境变量是可以由父进程继承给子进程的,那我们用execl环境替换,并不传递环境变量是否可以继承呢?

根据下图看起来没什么问题。

我们可以用函数 putenv 添加上环境变量,也是可以被继承的。

这里我们可以确定,程序替换,只会替换新进程的代码和数据,环境变量不会被替换

那么现在,我们可以将父进程的环境变量原封不动的传递给子进程了。

那么我们使用execle,并自己写环境变量,传递过去,看看是什么效果。

发现是覆盖,原来的环境变量没有了。

由此可以得知,环境变量的传递可以原封不动、可以新增、可以覆盖!!! 

直到了execle的使用,相信对于大家而言execvpe也不难了,这就不多赘述了。

其实这还有一个函数叫做execve,他是2手册的,我们学习的6个函数都是3号手册,execve是最底层的,这6个函数底层都调用了execve,他们主要是为了满足各种调用场景做出的不同。

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决:ModuleNotFoundError: No module named ‘paddle‘

错误显示&#xff1a; 原因&#xff1a; 环境中没有‘paddle’的python模块&#xff0c;但是您在尝试导入 解决方法&#xff1a; 1.普通方式安装&#xff1a; pip install paddlepaddle #安装命令 2.镜像源安装 pip install paddlepaddle -i https://pypi.tuna.tsinghua.e…

第18课:让客户看了就满意的商业软文是如何练成的?

选品上的注意事项 结合影视热点 通过追影视热点&#xff0c;找出能够跟产品贴合的点。在前面先道出痛点&#xff0c;痛点越深刻&#xff0c;用户对产品的过度才会更自然。 用户体验 真实体验才能真正写得出来。 结合时事热点 用的少&#xff0c;赶上了用就会效果很好&#xf…

C# Mel-Spectrogram 梅尔频谱

目录 介绍 Main features Philosophy of NWaves 效果 项目 代码 下载 C# Mel-Spectrogram 梅尔频谱 介绍 利用NWaves实现Mel-Spectrogram 梅尔频谱 NWaves github 地址&#xff1a;https://github.com/ar1st0crat/NWaves NWaves is a .NET DSP library with a lot …

Postman 接口自动化测试教程:入门介绍和从 0 到 1 搭建 Postman 接口自动化测试项目

关于Postman接口自动化测试的导引&#xff0c;全面介绍入门基础和从零开始搭建项目的步骤。学习如何有效地使用Postman进行API测试&#xff0c;了解项目搭建的基础结构、环境设置和测试用例的编写。无论您是新手还是经验丰富的测试人员&#xff0c;这篇教程都将为您提供清晰的指…

代码第二十四天-寻找旋转排序数组中的最小值Ⅱ

寻找旋转排序数组中的最小值Ⅱ 题目要求 解题思路 二分法 当遇到两个left、right两个位置值相同时候&#xff0c;可以选择将 right right-1 代码 class Solution:def findMin(self, nums: List[int]) -> int:left,right0,len(nums)-1while left<right:mid(leftright…

基于session注册JAva篇springboot

springboot3全家桶&#xff0c;数据库 &#xff1a;redis&#xff0c;mysql 背景环境&#xff1a;邮箱验证码&#xff0c;验证注册 流程&#xff1a;先通过邮箱验证&#xff0c;发送验证码&#xff0c;将获取到的session和验证码&#xff0c;存入redis里&#xff08;发送邮箱…

社区店运营方案分享:从推广到盈利的实战经验

对于想要开实体店或创业的朋友们&#xff0c;社区店是一个具有很大发展潜力的选择。 作为一名鲜奶吧5年的创业者&#xff0c;我将分享一些从推广到盈利的实战经验&#xff0c;希望能给大家提供有价值的参考。 1、市场调研&#xff1a; 在开店之前&#xff0c;深入了解社区的…

python 基础知识点(蓝桥杯python科目个人复习计划59)

今日复习内容&#xff1a;做题 例题1&#xff1a;建造房屋 问题描述&#xff1a; 小蓝和小桥是两位年轻的建筑师&#xff0c;他们正在设计一座新的城市。 在这个城市中&#xff0c;有N条街道&#xff0c;每条街道上有M个位置可以建造房屋&#xff08;一个位置只能建造一个房…

王道机试C++第 3 章 排序与查找:排序问题 Day28(含二分查找)

查找 查找是另一类必须掌握的基础算法&#xff0c;它不仅会在机试中直接考查&#xff0c;而且是其他某些算法的基础。之所以将查找和排序放在一起讲&#xff0c;是因为二者有较强的联系。排序的重要意义之一便是帮助人们更加方便地进行查找。如果不对数据进行排序&#xff0c;…

线性代数笔记13--正交向量和正交子空间

0. 四个子空间 1. 正交向量 两向量点乘为0&#xff0c;向量正交。 A ⊤ B 0 A^{\top}B0 A⊤B0 勾股定理 ∣ ∣ x ∣ ∣ 2 ∣ ∣ y 2 ∣ ∣ ∣ ∣ x y ∣ ∣ 2 ||x||^2||y^2||||xy||^2 ∣∣x∣∣2∣∣y2∣∣∣∣xy∣∣2 验证正交条件 ∣ ∣ x ∣ ∣ 2 x ⊤ x x x ⊤ ∣…

Qt ini配置文件

ini文件用于保存用户的设置操作&#xff0c;下列以背景颜色设置为例子 暂时默认设置为白色背景 这段代码放置在主窗口的构造函数中&#xff0c;用于初始化读取ini文件 QString color;QSettings *set new QSettings("color.ini",QSettings::IniFormat);set->begi…

Python语言基础与应用-北京大学-陈斌-P32-31-计算和控制流-上机练习:创建并调用函数-字符集合的并集-上机代码

Python语言基础与应用-北京大学-陈斌-P32-31-计算和控制流-上机练习&#xff1a;创建并调用函数-字符集合的并集-上机代码 本文环境&#xff1a; win10 Thonny4.1.4 # 函数训练字符集合的并集 def my_union(str1,str2):list1 []list2 []i 0 while i < len(str1):lis…