进程程序替换与exec系统调用

进程程序替换

进程程序替换是指将一个正在运行的进程替换为另一个可执行程序。它的本质是调用了Linux操作系统中的exec系统调用。而exec系统调用是一个家族函数,例如execlexecvexecleexecve等。它们的共同特点是当当前进程执行到该函数时,就会直接跳转到新的程序并开始执行新的可执行文件。

exec系统调用

所以我们要想知道怎样进行进程程序替换就要先会使用exec系统调用,而且exec系统调用的家族函数只要掌握了一个,其他的也就大差不差了。

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

所以就先详细的讲一下execl函数。

execl系统调用函数

#include <unistd.h>int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);

该函数接受可执行文件的路径(path)以及一系列的参数(arg0argn),最后以一个空指针(char *)0结尾。arg0代表可执行文件本身(即argv[0]),arg1argn是命令行参数。

代码示例

int main()
{cout<<"before execl"<<endl;//执行前execl("/usr/bin/ls","ls","-l","-a",NULL);//必须以空结束cout<<"after execl"<<endl;//执行后return 0;
}

 我们不难发现我们自己写的一个可执行程序运行的时候,在调用execl函数时会执行新的命令(可执行程序文件)而且在执行完成之后就直接结束了,并没有执行我们自己写的可执行程序的后续操作。就相当于在代码中调用其他程序。所以可以初步得出:execl函数成功执行时,当前进程将被替换为指定的可执行文件,并从该文件开始执行。注意,execl函数不会创建新的进程,而是将当前进程替换为新的可执行文件。

函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。

如果调用出错则返回-1
所以exec函数只有出错的返回值而没有成功的返回值。

执行原理

当我们运行我们的可执行程序时,该程序就已经变成了进程了,所以自然就少不了进程PCB以及进程地址空间和页表,和代码数据所映射的物理内存。但是当我们执行到execl函数时,就要开始执行一个已有的全新程序(并不创建进程),而该已有的程序(文件)自然存在磁盘当中,所以我们运行这个新的程序时就要将程序加载进内存。但是关键的是该新程序中的代码和数据并不是另存的,而是直接以覆盖式的存放在原进程的代码和数据所在物理内存中对应的位置,并继续从新程序的启动例程开始执行

以上就是单进程程序替换的过程

多进程的程序替换 

int main()
{pid_t i=fork();if(i==0)//子进程{    cout<<"before execl,"<<"mypid:"<<getpid()<<endl;execl("/usr/bin/ls","ls","-l","-a",NULL);//必须以空 结束cout<<"after execl,"<<"mypid:"<<getpid()<<endl;}else//父进程{pid_t ret=waitpid(-1,NULL,0);if(ret==i)cout<<"等待成功,"<<ret<<endl;}return 0;
}

我们知道开始我们就创建了一个子进程,而创建子进程的特点就是:数据独立以写时拷贝的方式存在,代码共享。而此时子进程执行execl函数,所以子进程就替换成了ls-a-l的一个程序,此时新程序的代码数据会覆盖在物理内存上。我们知道正常情况下父子进程数据发生改变时会以写时拷贝的方式另存空间,但是代码并不会。可是此时情况特殊,所以代码同样也会以写时拷贝的方式另存空间。归根结底还是:进程具有独立性

所以回到开始,为什么execl函数之后的代码不执行?其实就是程序替换,导致原进程的代码数据被新程序的代码数据覆盖,所以后续的代码自然就没有了,更不可能被执行。


其实我们的进程切换对语言是没要求的,可以自己随意地切换成其他语言的程序,不一定只切换成同语言的程序。

程序替换总结

程序替换是指将当前运行中的进程完全替换为一个新的程序。简单来说,就是将当前进程的代码、数据和堆栈等内容替换为新程序的代码、数据和堆栈。

当一个进程执行程序替换时,原来进程的代码、数据和堆栈被新程序覆盖,然后开始执行新程序的代码。这意味着原来进程的运行状态、打开的文件、socket连接等都会丢失,并且无法恢复。新程序从main函数开始执行,其运行过程与原程序无关。


而且对于需要传环境变量的exec类系统调用函数而言,环境变量属于全局的字符指针数组类型的变量environ,而且一个进程的环境变量是源于其父进程的环境变量,也就是说子进程会继承父进程的环境变量。不仅仅是创建子进程时会继承环境变量和命令行参数,而对于进程切换时也是会继承下来的。而对于进程替换而言原进程会采用覆盖环境变量内容的方式让新的进程继承下来,也就是说如果原进程调用函数接口时传入的环境变量是自己写的环境变量的话,那么切换的新进程会将原进程的环境变量里的内容继承下来。但是如果不想覆盖式传递的话可以采用putenv(char* env_val)函数在原环境变量表里去添加新的环境变量env_val,此时就不会清空原环境变量里的内容,而是添加内容后的环境变量传递给新的进程main函数的第三个参数当中。

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

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

相关文章

Bert浅谈

优点 首先&#xff0c;bert的创新点在于利用了双向transformer&#xff0c;这就跟openai的gpt有区别&#xff0c;gpt是采用单向的transformer&#xff0c;而作者认为双向transformer更能够融合上下文的信息。这里双向和单向的区别在于&#xff0c;单向只跟当前位置之前的tocke…

Nginx安装配置与SSL证书安装部署

一、Nginx Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;被广泛用于构建现代化的Web应用和提供静态内容。 nginx官网 这里下载nginx-1.24.0-zip Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;被广泛用于构建现代化的Web应用和提供静态内…

测试开发环境下centos7.9下安装docker的minio

按照以下方法进行 1、安装docker&#xff0c;要是生产等还是要安装docker-ce yum install docker 2、启动docker service docker start 3、 查看docker信息 docker info 4、加到启动里 systemctl enable docker.service 5、开始docker pull minio/minio 但报错&#x…

【机器学习7】优化算法

1 有监督学习的损失函数 1.1 分类问题 对二分类问题&#xff0c; Y{1,−1}&#xff0c; 我们希望sign f(xi,θ)yi&#xff0c; 最自然的损失函数是0-1损失&#xff0c; 函数定义特点0-1损失函数非凸、非光滑&#xff0c;很难直接对该函数进行优化Hinge损失函数当fy≥1时&…

汽车以太网IOP测试新利器

IOP测试目的 汽车以太网物理层IOP&#xff08;Interoperability &#xff09;测试&#xff0c;即测试被测对象以太网物理层之间的互操作性。用于验证车载以太网PHY能否在有限时间内建立稳定的链路&#xff1b;此外&#xff0c;还用于验证车载以太网PHY可靠性相关的诊断特性&am…

Linux环境下C++ 接入OpenSSL

接上一篇&#xff1a;Windows环境下C 安装OpenSSL库 源码编译及使用&#xff08;VS2019&#xff09;_vs2019安装openssl_肥宝Fable的博客-CSDN博客 解决完本地windows环境&#xff0c;想赶紧在外网环境看看是否也正常。毕竟现在只是HelloWorld级别的&#xff0c;等东西多了&am…

浅谈智能安全配电装置应用在银行配电系统中

【摘要】银行是国家重点安全保护部分&#xff0c;关系到社会资金的稳定&#xff0c;也是消防重点单位。消防安全是银行工作的重要组成部分。在银行配电系统中应用智能安全配电装置&#xff0c;可以提高银行的智能控制水平&#xff0c;有效预防电气火灾。 【关键词】银行&#…

如何快速下载mysql的不同版本并启动mysql服务?

如何快速下载mysql的不同版本并启动mysql服务&#xff1f; 下载mysql的安装版本 首先我们要使用到迅雷去下载&#xff0c;因为迅雷下载是很快的。在迅雷里面搜索下面的Mysql Installer安装窗口&#xff0c;如下图&#xff1a; 连接&#xff1a;https://dev.mysql.com/downlo…

fopen/fwrite/fread 对UNICODE字符写入的总结

windows对fopen函数进行了升级&#xff0c;可以支持指定文件的编码格式&#xff08;ccs参数指定&#xff09;。 例如&#xff1a; FILE *fp fopen("newfile.txt", "rt, ccsUTF-8"); 当以 ccs 模式打开文件时&#xff0c;进行读写操作的数据应为 UTF-16…

Selenium自动化测试框架

一.Selenium概述 1.1 什么是框架? 框架&#xff08;framework&#xff09;是一个框子——指其约束性&#xff0c;也是一个架子——指其支撑性。是一个基本概念上的 结构用于去解决或者处理复杂的问题。 框架是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及…

【Machine Learning in R - Next Generation • mlr3】

本篇主要介绍mlr3包的基本使用。 一个简单的机器学习流程在mlr3中可被分解为以下几个部分&#xff1a; 创建任务 比如回归、分裂、生存分析、降维、密度任务等等挑选学习器&#xff08;算法/模型&#xff09; 比如随机森林、决策树、SVM、KNN等等训练和预测 创建任务 本次示…

C语言每日一题(32)环形链表

力扣网 141.环形链表 题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾…

LLM大模型4位量化实战【GPTQ】

权重量化方面的最新进展使我们能够在消费类硬件上运行大量大型语言模型&#xff0c;例如 RTX 3090 GPU 上的 LLaMA-30B 模型。 这要归功于性能下降最小的新型 4 位量化技术&#xff0c;例如 GPTQ、GGML 和 NF4。 在上一篇文章中&#xff0c;我们介绍了简单的 8 位量化技术和出…

GZ038 物联网应用开发赛题第10套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 &#xff08;第10套卷&#xff09; 工位号&#xff1a;______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具&#xff0c;操作安全规范&#xff1b; 2、竞赛过程中如有异议&#xff0c;可向现场考…

Spring学习③__Bean管理

目录 IOC接口ApplicationContext 详解IOC操作Bean管理基于xml方式基于xml方式创建对象基于xml方式注入属性使用set方法进行注入通过有参数的构造进行注入p 名称空间注入&#xff08;了解&#xff09; 基于xml方式注入其他类型属性xml 注入数组类型属性 IOC接口 IOC思想基于IOC…

Linux 无名管道实现文件复制

无名管道 通过一个管道&#xff08;假象&#xff09;进行传输数据&#xff0c;但是这个管道的传输方式是单工&#xff08;半双工&#xff09;的&#xff0c;就是这个管道允许进行发送和接受数据&#xff0c;不过不能同时进行。 创建无名管道 这里用到一个pipe&#xff08;&…

代码随想录算法训练营第三十九天【动态规划part02】 | 62.不同路径、63. 不同路径 II

62.不同路径 题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 求解思路&#xff1a; 动规五部曲 确定dp数组及其下标含义&#xff1a;dp[i][j] 表示从&#xff08;0,0&#xff09;出发&#xff0c;到&#xff08;i,j&#x…

性能测试【第三篇】Jmeter的使用

线程数:10 ,设置10个并发 Ramp-Up时间(秒):所有线程在多少时间内启动,如果设置5,那么每秒启动2个线程 循环次数:请求的重复次数,如果勾选"永远"将一直发送请求 持续时间时间:设置场景运行的时间 启动延迟:设置场景延迟启动时间 响应断言 响应断言模式匹配规则 包括…

AIGC创作系统ChatGPT源码,AI绘画源码,支持最新GPT-4-Turbo模型,支持DALL-E3文生图

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…