linux下的进程程序替换

进程程序替换

  • 替换概念
  • 替换函数
    • 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 328 int main()9 {10   pid_t id = fork();11 12   if(id == 0)13   {14     //子进程15     // ls -a -l16     printf("子进程开始执行,pid = %d \n",getpid());17     //传入指针数组18     char *const _argv[NUM] = {19      (char*)"ls",20      (char*)"-l",21       (char*)"-i",22       NULL23     };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 328 int main()9 {10   pid_t id = fork();11 12   if(id == 0)13   {14     //子进程15     // ls -a -l16     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 328 int main()9 {10 11   //设置一个环境变量,为的是 让子进程拿到12   //因为环境变量具有全局属性13   char *const _env[NUM]={14     (char*)"xty=123456789",15     NULL16   };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.mzph.cn/news/206504.shtml

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

相关文章

爬虫 selenium语法 (八)

目录 一、为什么使用selenium 二、selenium语法——元素定位 1.根据 id 找到对象 2.根据标签属性的属性值找到对象 3.根据Xpath语句获取对象 4.根据标签名获取对象 5.使用bs语法获取对象 6.通过链接文本获取对象 三、selenium语法——访问元素信息 1.获取属性的属性值…

有爱的冬天不再冷——壹基金儿童温暖包抵达富平

12月6日&#xff0c;富平县帮帮乐公益协会组织志愿者在协会楼下分装了由爱心企业、个人捐赠的144个壹基金儿童温暖包&#xff0c;争取在下周寒流来临前送到困境儿童手中&#xff0c;温暖他们的整个冬天。 壹基金温暖包项目是针对6—12岁困境儿童、留守儿童设计的暖冬应急生活物…

MySQL数据库sql语句操作

一、数据库模型 关系型数据库是一种以表格形式组织和存储数据的数据库。它使用关系模型&#xff0c;其中数据被组织为多个表格&#xff0c;每个表格包含了多个行和列。每个表格的列描述了数据的属性&#xff0c;而行包含了实际的数据记录。 非关系型数据库&#xff0c;也称为…

使用命令行创建vue3项目等待时间长解决方案

问题描述 今天在使用命令行创建vue3项目的时候&#xff0c;发现命令行窗口卡了很久&#xff0c;明明已经更换了安装包的源&#xff0c;并且检查环境变量配置正确的情况下&#xff0c;为什么还要等待那么久呢&#xff1f; 解决方案 使用命令再次检查更换淘宝的源是否配置成功…

玩转系统|利用HestiaCP自建NS解析及邮局并利用MailGun进行发信

前述 HestiaCP是一个VestaCP分叉来的产物&#xff0c;而同样作为VestaCP分叉来的myVesta也具有类似的功能。VestaCP本身作为一个社区的产区&#xff0c;其仅仅有一个商业插件需要每月付费5USD进行使用&#xff0c;因此为了达到完全开放使用的目的&#xff0c;这里选择使用Hest…

小电流MOSFET 选型分析数据,可应用于电子烟,电动工具,智能穿戴等产品上

小电流双N&#xff0c;D-N通道MOSFET&#xff0c;电压60V-100V左右 电流300mA-500MA&#xff0c;采用封装形式多样。具有低导通电阻&#xff0c;可快速切换速度&#xff0c;易于设计的驱动电路也易于并联&#xff0c;ESD保护&#xff0c;低电压驱动使该器件非常适合便携式设备…

通俗易懂的案例+代码解释AOP 切面编程

目录 1. 理解AOP2 Before2.1 controller层2.2 service层2.3 自定义注解2.4 切面 advice 3 After4 Around spring的三大核心&#xff1a;IOC控制反转、DI依赖注入、AOP面向切面编程 刚开始接触springboot项目&#xff0c;前两个使用的多&#xff0c;亲自使用AOP的机会并不多&…

【学习笔记】python仅拷贝list的值,引出浅拷贝与深拷贝

一、python 仅拷贝list的值&#xff08;来源于gpt&#xff09; 在 Python 中&#xff0c;可以使用切片或 copy() 方法来仅拷贝列表的值。 1、使用切片 a [1, 2, 3, 4, 5] b a[:] # 通过切片来拷贝 a 的值 在上面的代码中&#xff0c;我们使用切片来拷贝列表 a 的值&#xff…

长城之上的无人机:文化遗产的守护者

长城之上的无人机&#xff1a;文化遗产的守护者 在八达岭长城景区&#xff0c;两架无人机分别部署在了长城的南、北楼两点。根据当前的保护焦点和需求&#xff0c;制定了5条无人机综合巡查航线&#xff0c;以确保长城景区的所有开放区域都能得到有效监管。每天&#xff0c;无人…

【LeetCode】2703. 返回传递的参数的长度

返回传递的参数的长度 题目题解 题目 请你编写一个函数 argumentsLength&#xff0c;返回传递给该函数的参数数量。 示例 1&#xff1a; 输入&#xff1a;args [5] 输出&#xff1a;1 解释&#xff1a; argumentsLength(5); // 1只传递了一个值给函数&#xff0c;因此它应返…

zabbix、netdata和glances,做最简单的系统资源监控

软件需要显示服务器的资源信息&#xff08;CPU、内存、网络、硬盘等&#xff09;&#xff0c;但是软件是在Docker容器中运行。 目前方案 通过ssh在主机上远程运行ps、free等指令&#xff0c;获取相应的信息。这种方案需要代码配置主机的IP&#xff0c;以及用户名和密码&#…

干爆ChatGPT,谷歌发布新大模型:Gemini

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 谷歌昨天又发布了一个新的大模型&#xff0c;叫Gemini(双子座时代)。打开Google AI 就能看到。 据说非常强&#xff0c;然后是一大堆夸奖&#xff0c;大概是本月中旬的时候正式推出。标题明晃晃写…

Java UDP 多人聊天室简易版

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

Rask AI引领革新,推出多扬声器口型同步技术,打造本地化内容新纪元

“ Rask AI是一个先进的AI驱动视频和音频本地化工具&#xff0c;旨在帮助内容创作者和公司快速、高效地将他们的视频转换成60多种语言。通过不断创新和改进产品功能&#xff0c;Rask AI正塑造着未来媒体产业的发展趋势。 ” 在多语种内容创作的新时代&#xff0c;Rask AI不断突…

Day53力扣打卡

打卡记录 重新规划路线&#xff08;dfs&#xff09; 链接 class Solution:def dfs(self, x: int, parent: int, e: List[List[List[int]]]) -> int:res 0for edge in e[x]:if edge[0] parent:continueres edge[1] self.dfs(edge[0], x, e)return resdef minReorder(se…

基于AWS Serverless的Glue服务进行ETL(提取、转换和加载)数据分析(三)——serverless数据分析

3 serverless数据分析 大纲 3 serverless数据分析3.1 创建Lambda3.2 创建API Gateway3.3 结果3.4 总结 3.1 创建Lambda 在Lambda中&#xff0c;我们将使用python3作为代码语言。 步骤图例1、入口2、创建&#xff08;我们选择使用python3.7&#xff09;3、IAM权限&#xff08;…

第二十一章——网络通信总结

网络程序设计基础 局域网与互联网 为了实现两台计算机的通信&#xff0c;必须用一个网络线路连接两台计算机。如下图所示 网络协议 1.IP协议 IP是Internet Protocol的简称&#xff0c;是一种网络协议。Internet 网络采用的协议是TCP/IP协议&#xff0c;其全称是Transmission…

展望2024年供应链安全

2023年是开展供应链安全&#xff0c;尤其是开源治理如火如荼的一年&#xff0c;开源治理是供应链安全最重要的一个方面&#xff0c;所以我们从开源治理谈起。我们先回顾一下2023的开源治理情况。我们从信通院《2023年中国企业开源治理全景观察》发布的信息。信通院调研了来自七…

渐进式web全栈blazor web

渐进式 vue是渐进式web前端框架&#xff0c;所谓的渐进式就是你不用一开始就整个项目全部使用vue&#xff0c;因为开始你可能并不熟悉vue&#xff0c;而是开始只使用vue的些简单功能&#xff0c;慢慢用它更复杂更好的功能&#xff0c;最终项目可能完全使用vue。 渐进式blazor…

1+x网络系统建设与运维(中级)-练习题4

一.设备命名 LSW1 <Huawei>sys [Huawei]sysn LSW1 [LSW1]un in en 同理可得&#xff0c;给所有设备如以上命令一样配置 二.VLAN LSW1 [LSW1]vlan ba 1 10 20 100 [LSW1]int g0/0/1 [LSW1-GigabitEthernet0/0/1]port link-type trunk [LSW1-GigabitEthernet0/0/1]port tru…