linux下的进程程序替换

news2024/11/18 7:51:14

进程程序替换

  • 替换概念
  • 替换函数
    • execl()
    • execv()
    • execvp()/execlp()
    • execle()/execvpe()
  • 如何在C/C++程序里面执行别的语言写的程序。
    • 小tips

替换概念

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

大概意思就是程序替换只是把程序换了,仅仅是从1号程序换到了2号程序,修改了页表的映射地址,但是并没有创建新的PCB,因此没有创建新的进程。
这就是进程替换的概念!
在这里插入图片描述

替换函数

在linux手册里,有6个相似的函数,他们虽然参数列表不一样,但是功能一样。
在这里插入图片描述

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

execl()

l:列表的形式传入参数

int extcl(const char * path, const char* argv,…);
参数:
path:是要打开可执行程序的路径
argv,… :这个语法表示可变的参数列表,可以传入多个不定个数的参数,最后一个参数传入NULL,表示参数传递完成。

描述不清楚,看个例子就明白了:

  1 #include<stdio.h>
  2 #include<unistd.h>

  5 int main()
  6 {
  7   printf("当前进程开始!\n");
  8   //execl("/usr/bin/ls","ls","--color=auto","-l",NULL);
  9   //一旦调用成功,后续代码都不会执行了!!!                                                                                                                            
 10   execl("/usr/bin/ls","ls","--color=auto","-l", "-i",NULL);
 11   //execl("/usr/bin/top", "top", NULL);
 12   printf("当前进程结束!\n");                                                                                                                                   
 13   return 0;                                                                                                                                                     
 14 }      

因为Linux系统下一切皆文件,ls命令其实就是一个可执行程序,我们使用execl函数,执行这个程序。我们可以改变可变参数列表来使用ls命令不同的功能。
在这里插入图片描述

execv()

v:数组的形式传入参数

int extcv(const char * path, char *const argv[]);
参数:
path:仍然是文件路径。
char *argv[]:指针数组,以数组的形式传入。

为了更加适应实际的应用场景,我们使用父进程fork子进程,然后使用子进程进行进程替换,这样不会影响父进程的执行。
如下:

7 #define NUM 32
  8 int main()
  9 {
 10   pid_t id = fork();
 11 
 12   if(id == 0)
 13   {
 14     //子进程
 15     // ls -a -l
 16     printf("子进程开始执行,pid = %d \n",getpid());
 17     //传入指针数组
 18     char *const _argv[NUM] = {
 19      (char*)"ls",
 20      (char*)"-l",
 21       (char*)"-i",
 22       NULL
 23     };
 24     execv("/usr/bin/ls",_argv);  //传入指针数组!!!
 25     exit(1);
 26   }
 27   else{
 28     //父进程
 29     printf("父进程开始等待,pid =%d \n", getpid());                                                                                                                     
 30     int status = 0;
 31     pid_t ret = waitpid(-1, &status, 0); //阻塞等待
 32     if(ret>0)
 33     {
 34       printf("等待成功,退出码为:%d \n", WEXITSTATUS(status));
 35     }
 36   }
 37   return 0;
 38 }

在这里插入图片描述
可以看到,子进程帮助父进程完成了执行ls命令,并且没有影响父进程的执行。

execvp()/execlp()

p:表明第一个参数不再是文件路径,而是通过环境变量就可以找到的程序。
看下面的例子更能清楚的解释:

execvp()的例子:

  7 #define NUM 32
  8 int main()
  9 {
 10   pid_t id = fork();
 11 
 12   if(id == 0)
 13   {
 14     //子进程
 15     // ls -a -l
 16     printf("子进程开始执行,pid = %d \n",getpid());
 17     //传入指针数组
 18     char *const _argv[NUM] = {
 19      (char*)"ls",  
 20      (char*)"-l",  
 21       (char*)"-i",  
 22       NULL  
 23     };  
 24     //execv("/usr/bin/ls",_argv);  
 25     execvp("ls",_argv);   //因为环境变量的存在,我们可以只输入ls便可找到该文件。                                                                                        
 26     exit(1);                                             
 27   }                                                                                                                              
 28   else{                                                                                                                          
 29     //父进程                                                                                                                     
 30     printf("父进程开始等待,pid =%d \n", getpid());                                                                              
 31     int status = 0;                                                                                                              
 32     pid_t ret = waitpid(-1, &status, 0); //阻塞等待                                                                              
 33     if(ret>0)                                                                                                                    
 34     {                                                                                                                            
 35       printf("等待成功,退出码为:%d \n", WEXITSTATUS(status));                                                                   
 36     }                                                                                                                            
 37   }                                                                                                                              
 38   return 0;
 39 }

在这里插入图片描述

execlp()例子:
仅仅将上面的代码,25行换成26行的内容即可!

   25     //execvp("ls",_argv);   //因为环境变量的存在,我们可以只输入ls便可找到该文件。                                                                   
   26     execlp("ls", "ls", "-l", "-i", NULL);        

execle()/execvpe()

e:可以维护自己的环境变量,将环境变量传给要替换的进程。

以execle为例:
将上面的子进程调用部分修改:

    7 #define NUM 32
    8 int main()
    9 {
   10 
   11   //设置一个环境变量,为的是 让子进程拿到
   12   //因为环境变量具有全局属性
   13   char *const _env[NUM]={
   14     (char*)"xty=123456789",
   15     NULL
   16   };

   31     execle("./myexe", "mycmd", "-a", NULL, _env);   //修改成这样,//其中列表参数是随便传的,myexe是调用的可执行程序。
myexe:
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main()
  5 {
  6                                                                                                                                                                         
  7   printf("得到的环境变量xty:%s\n", getenv("xty"));
  8   return 0;
  9 }

在这里插入图片描述

可知myexe获取到了环境变量。

如何在C/C++程序里面执行别的语言写的程序。

在这里插入图片描述

//使用这个命令即可运行
python test.py

在这里插入图片描述

首先写一个python文件脚本。待会我们就是用c程序执行它。
使用execlp()调用比较合适。

  1 #include <stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6 int main()
  7 {
  8   pid_t id = fork();
  9   if(id == 0)
 10   {
 11     //子进程,调用别的语言写的程序
 12     execlp("python", "python", "test.py", NULL);
 13     exit(-1);
 14   }
 15   else{
 16     //父进程
 17     int status = 0;
 18     printf("父进程开始等待: \n");
 19     int ret = waitpid(-1, &status, 0); //阻塞等待
 20     if(ret > 0)
 21     {
 22       printf("父进程等待成功,子进程退出码为:%d \n",WEXITSTATUS(status));
 23 
 24     }
 25   }                                                                                                                                                                     
 26   return 0;
 27 }

在这里插入图片描述
我们可以看出python脚本被我们成功调用!

小tips

我们在运行py脚本时,需要运行python这个程序。因为python是一个解释器,我们需要使用解释器来解释test.py文件。

python test.py

如果我们给该test.py文件加上执行(x)权限,那么我们这样即可运行该文件:

在这里插入图片描述

因此将上面的execlp调用参数,修改为下面这样也可以:

 //12     execlp("python", "python", "test.py", NULL);
 12     execlp("./test.py", "test.py", NULL);

上面就是程序替换的相关知识,更深入的内容还请读者自行查阅和学习。

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

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

相关文章

案例005:基于小程序的电子点菜系统开发设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【机器学习】亚马逊云科技基础知识:以推荐系统为例。你知道机器学习的关键所在么?| 机器学习管道的各个阶段及工作:以Amazon呼叫中心转接问题为例讲解

有的时候,暂时的失利比暂时胜利要好得多。 ————经典网剧《mao pian》,邵半仙儿 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能领域TOP

MongoDB中的sort()排序方法、aggregate()聚合方法和索引

本文主要介绍MongoDB中的sort()排序方法、aggregate()聚合方法和索引。 目录 MongoDB的sort()排序方法MongoDB的aggregate()聚合方法MongoDB的索引 MongoDB的sort()排序方法 在MongoDB中&#xff0c;sort()方法是用来对查询结果进行排序的。sort()方法可以用于在查询语句中对指…

红队攻防实战之ThinkPHP-RCE集锦

你若不勇敢&#xff0c;谁又可以替你坚强&#xff1f; ThinkPHP 2.x RCE漏洞 1、查询phpinfo() 2、任意代码执行 3、Getshell 蚁剑连接&#xff1a; ThinkPHP5 5.0.23 RCE漏洞 发送数据包&#xff1a; 成功执行id命令&#xff1a; 工具验证 ThinkPHP5 SQL注入漏洞 &&am…

Android开发,JNI,NDK,C++层操作java的对象实践

Android开发&#xff0c;JNI&#xff0c;NDK&#xff0c;C层操作java的对象实践 1.数组 在jni中调用数组 extern "C" JNIEXPORT void JNICALL Java_com_example_myapplication_MainActivity_testArr(JNIEnv *env, jobject thiz, jint a, jstring s,jintArray ints…

Axure网页端高交互组件库, 下拉菜单文件上传穿梭框日期城市选择器

作品说明 组件数量&#xff1a;共 11 套 兼容软件&#xff1a;Axure RP 9/10&#xff0c;不支持低版本 应用领域&#xff1a;web端原型设计、桌面端原型设计 作品特色 本作品为「web端组件库」&#xff0c;高保真高交互 (带仿真功能效果)&#xff1b;运用了动态面板、中继…

LNMP网站架构分布式搭建部署

1. 数据库的编译安装 1. 安装软件包 2. 安装所需要环境依赖包 3. 解压缩到软件解压缩目录&#xff0c;使用cmake进行编译安装以及模块选项配置&#xff08;预计等待20分钟左右&#xff09;&#xff0c;再编译及安装 4. 创建mysql用户 5. 修改mysql配置文件&#xff0c;删除…

如何为游戏角色3D模型设置纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xf…

【面试经典150 | 二叉树】从中序与后序遍历序列构造二叉树

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;递归 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容…

股票放量成交后,大涨的概率有多少?

很多时候&#xff0c;经常有人会感觉&#xff0c;成交量突然放大5倍以上&#xff0c;后面的股价大概率会上涨&#xff0c;很多投顾班的老师也是给大家展示这样的感觉&#xff0c;那究竟有多大比例的上涨呢&#xff1f; 【文章仅是数据分析&#xff0c;不构成任何投资建议】 一…

ROS gazebo 机器人仿真,环境与robot建模,添加相机 lidar,控制robot运动

b站上有一个非常好的ros教程234仿真之URDF_link标签简介-机器人系统仿真_哔哩哔哩_bilibili&#xff0c;推荐去看原视频。 视频教程的相关文档见&#xff1a;6.7.1 机器人运动控制以及里程计信息显示 Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 本文对视频教程…

工业4.0分类:数字化转型的多维度

引言 工业4.0代表着制造业的数字化革命&#xff0c;它将制造过程带入了数字时代。然而&#xff0c;工业4.0并不是一个单一的概念&#xff0c;而是一个多维度的范畴&#xff0c;包括不同的技术、应用领域、企业规模和实施方式。但在这一多维度的概念中&#xff0c;低代码技术正…

CSS新手入门笔记整理:CSS浮动布局

文档流概述 正常文档流 “文档流”指元素在页面中出现的先后顺序。正常文档流&#xff0c;又称为“普通文档流”或“普通流”&#xff0c;也就是W3C标准所说的“normal flow”。正常文档流&#xff0c;将一个页面从上到下分为一行一行&#xff0c;其中块元素独占一行&#xf…

【刷题】位运算

2 n 2^n 2n 1<<n判断某一位是否为1 s&1<<k将上面两个组合&#xff0c;可以得到判断一个集合中哪些内容包含&#xff0c;遍历所有情况。 100140. 关闭分部的可行集合数目 一个公司在全国有 n 个分部&#xff0c;它们之间有的有道路连接。一开始&#xff0c;…

网络攻击(二)--情报搜集阶段

4.1. 概述 在情报收集阶段&#xff0c;你需要采用各种可能的方法来收集将要攻击的客户组织的所有信息&#xff0c;包括使用社交网络、Google Hacking技术、目标系统踩点等等。 而作为渗透测试者&#xff0c;你最为重要的一项技能就是对目标系统的探查能力&#xff0c;包括获知…

kafka学习笔记--生产者消息发送及原理

本文内容来自尚硅谷B站公开教学视频&#xff0c;仅做个人总结、学习、复习使用&#xff0c;任何对此文章的引用&#xff0c;应当说明源出处为尚硅谷&#xff0c;不得用于商业用途。 如有侵权、联系速删 视频教程链接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;从入门到调优…

深度学习记录--神经网络表示及其向量化

神经网络表示 如下图 就这个神经网络图来说&#xff0c;它有三层&#xff0c;分别是输入层(Input layer)&#xff0c;隐藏层(Hidden layer)&#xff0c;输出层(Output layer) 对于其他的神经网络&#xff0c;隐藏层可以有很多层 一般来说&#xff0c;不把输入层算作一个标准…

Idea的Marketplace下载不了插件,idea下不了插件

Idea的Marketplace下载不了插件 解决方案&#xff08;配置代理&#xff09; 附一张成功界面 2.问题复现 3.问题原因和解决方式&#xff1a;下载安装IDEA之后HTTP Proxy没有进行相关配置的问题&#xff0c;解决方式如下 1.首先打开file->setting->Appearance & B…

【设计模式-4.4】行为型——模板方法模式

说明&#xff1a;本文介绍设计模式中行为型设计模式中的&#xff0c;模板方法模式&#xff1b; 生存 模版方法模式是行为型设计模式&#xff0c;关注于对象的行为。在《秒懂设计模式》&#xff08;刘韬 著&#xff09;中举了一个例子&#xff0c;例如哺乳动物的生存技能&…

【python交互界面】实现动态观察图像在给定HSV范围的区域显示

HSV颜色空间 与RGB颜色空间相比&#xff0c;HSV颜色空间更适合进行颜色分析和提取特定颜色的目标。在HSV空间中&#xff0c;颜色信息被分布在不同的通道上&#xff0c;使我们能够更准确地定义颜色的范围&#xff0c;并使用阈值操作轻松地分离出我们感兴趣的区域部分。 HSV三个通…