Linux--进程的程序替换

news2025/7/28 6:26:18

问题导入:

前面我们知道了,fork之后,子进程会继承父进程的代码和“数据”(写实拷贝)。

那么如果我们需要子进程完全去完成一个自己的程序怎么办呢?

进程的程序替换来完成这个功能!

1.替换原理

⽤fork创建⼦进程后执⾏的是和⽗进程相同的程序(但有可能执⾏不同的代码分⽀),⼦进程往往要调⽤⼀种 exec函数 以执⾏另⼀个程序。当进程调⽤⼀种exec函数时,该进程的⽤⼾空间代码和数据完全被新程序替换,从新程序的启动例程开始执⾏。调⽤exec并不创建新进程,所以调⽤exec前后该进程的id并未改变。
我们先用一个简单的示例来见见进程替换:
int execl(const char *path, const char *arg, ...);

利用最简单的exec函数,这里的path是可执行程序的地址,文件的地址可以用指针来表示,const char *arg,...这里表示可变参数,说明可以传入多个参数。

1.1可变参数

具体可见:

C 语言通过 <stdarg.h> 实现可变参数,图里重点用到这些:

  • va_list参数列表类型,本质是指针(比如 va_list args ,用来 “指向” 可变参数在栈里的位置)。
  • va_start(args, count)初始化,让 args 指向可变参数的 “起始位置”(count 是固定参数,用来定位可变参数从哪开始)。
  • va_arg(args, double)逐个取参数,按类型(这里是 double)从栈里读数据,读完后 args 自动指向下一个参数。
  • va_end(args)收尾清理,释放 va_list 相关资源(有些环境里是 “形式上” 的规范,实际也需调用)。

 栈内存视角:参数怎么存?

右侧 “栈帧”(main 调用 sum 的栈结构)是关键:

  • 固定参数count(图里是 3)是固定参数,先入栈,用来告诉函数 “可变参数有几个”。
  • 可变参数1.02.03.0 这些可变参数,按从右到左顺序入栈(C 语言调用约定常见规则),存在栈里等待读取。
 

代码里 sum(3, 1.0, 2.0, 3.0) 调用时,栈里布局大致是:

 
高地址 →  [count=3]  [1.0]  [2.0]  [3.0]  ← 低地址  
 

(实际栈增长方向是 “高地址 → 低地址”,但参数入栈顺序是 3 先压,然后 1.02.03.0 依次压,所以低地址侧是可变参数)

 代码流程:怎么读可变参数?

结合图里 sum 函数逻辑,流程是:

  1. 初始化va_start(args, count) → 让 args 指向可变参数起始位置(跳过固定参数 count,指向第一个可变参数 1.0 所在栈地址 )。
  2. 循环读取va_arg(args, double) → 每次按 double 类型从栈里取数据,累加到 total。取完后,args 自动偏移(因为 double 占 8 字节,所以 args 会 += sizeof(double) 指向下一个参数 )。
  3. 收尾va_end(args) → 释放资源,结束可变参数处理。

 类比 printf:可变参数的 “通用逻辑”

图里也提到 printf(const char *format, ...) ,它的逻辑和 sum 类似:

 
  • format 是固定参数(类似 count),用来 “描述可变参数的类型、个数”(比如 %d 对应 int%f 对应 double )。
  • 内部也是用 va_list 读取可变参数,按 format 里的占位符,逐个解析栈里的数据。

1.2 简单使用

知道可变参数之后我们开始简单使用一下execl,

通过以上例子我们提出两个疑问。

(1)为什么没打印“进程结束”?

(2)如果是在子进程中执行exec可以替换子进程的代码的数据吗?

好的,我们一一解决

(1)为什么没打印“进程结束”?

        替换了,你的进程,已经执行另一个程序的代码了你自己的代码,已经没有了!!

        程序替换函数,一旦调用成功,后续代码,不在执行,因为没有了!

如果失败呢??

        失败的话就会回到原代码,并且exe系列函数会有一个返回值,exe系列的函数,只要返回,必然失败! 程序替换,如果成功,不需要,也不会有返回值! 失败返回-1

(2)如果是在子进程中执行exec可以替换子进程的代码的数据吗?

子进程执行一个全新的程序,会影响父进程吗?不会!!进程必须具有独立性(父子代码共享,数据写时拷贝啊)

你可以理解成为,代码如果被替换,也要进行写时拷贝,会在内存中为子进程开辟数据的代码的空间。

由此可见,execl在这里就是起到一个加载器的作用。

2.exe家族的其他接口

这里我们在linux的命令行中man 一下exec。

可见,这里有六个接口,其实有七个,还有一个我们稍后再讲。

2.1命名理解

这些函数原型看起来很容易混,但只要掌握了规律就很好记。
l(list) : 表⽰参数采⽤列表
v(vector) : 参数⽤数组
p(path) : 有p⾃动搜索环境变量PATH
e(env) : 表⽰⾃⼰维护环境变量
函数名参数格式是否带路径是否使用当前环境变量
execl列表不是
execlp列表
execle列表不是不是,须自己组装环境变量
execv数组不是
execvp数组
execve数组不是不是,须自己组装环境变量

2.2exe家族的使用 

#include <stdio.h>
#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);
}

函数的使用比较简单,可以拿着格式自己试试,同时需要注意的是,这里的argv和envp是我们之前学到的命令行参数和环境变量,可以拿自己也可以直接在main函数中接收,可以直接拿着父进程的用,如果都要可以使用putenv()函数。

还有个点值得注意,在你的进程的地址空间,就如同全局变量一样,如果你不以参数形式传递给子进程,子进程也照样能拿到!!!!地址空间和页表!!!

3.六个接口与第七个的关系

上面我们不是提到了第七个接口,其实他叫做execve。

事实上,只有execve是真正的系统调⽤,其它六个函数最终都调⽤execve,所以execve在man⼿册 第2节, 其它函数在man⼿册第3节。
这些函数之间的关系如下图所⽰

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

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

相关文章

调教 DeepSeek - 输出精致的 HTML MARKDOWN

【序言】 不知道是不是我闲的蛋疼&#xff0c;对百度AI 和 DeepSeek 的回答都不太满意。 DeepSeek 回答句子的引用链接&#xff0c;始终无法准确定位。有时链接只是一个域名&#xff0c;有时它给的链接是搜索串如: baidu.com/?q"搜索内容"。 百度AI 回答句子的引用…

【笔记】Windows系统部署suna基于 MSYS2的Poetry 虚拟环境backedn后端包编译失败处理

基于 MSYS2&#xff08;MINGW64&#xff09;中 Python 的 Poetry 虚拟环境包编译失败处理笔记 一、背景 在基于 MSYS2&#xff08;MINGW64&#xff09;中 Python 创建的 Poetry 虚拟环境里&#xff0c;安装 Suna 开源项目相关包时编译失败&#xff0c;阻碍项目正常部署。 后端…

【深度学习优化算法】02:凸性

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

策略公开了:年化494%,夏普比率5.86,最大回撤7% | 大模型查询akshare,附代码

原创内容第907篇&#xff0c;专注智能量化投资、个人成长与财富自由。 这位兄弟的策略公开了&#xff0c;年化494%&#xff0c;夏普比率5.86&#xff0c;最大回撤7%&#xff0c;欢迎大家前往围观&#xff1a; http://www.ailabx.com/strategy/683ed10bdabe146c4c0b2293 系统代…

多模态大语言模型arxiv论文略读(101)

ML-Mamba: Efficient Multi-Modal Large Language Model Utilizing Mamba-2 ➡️ 论文标题&#xff1a;ML-Mamba: Efficient Multi-Modal Large Language Model Utilizing Mamba-2 ➡️ 论文作者&#xff1a;Wenjun Huang, Jiakai Pan, Jiahao Tang, Yanyu Ding, Yifei Xing, …

电网“逆流”怎么办?如何实现分布式光伏发电全部自发自用?

2024年10月9日&#xff0c;国家能源局综合司发布了《分布式光伏发电开发建设管理办法&#xff08;征求意见稿&#xff09;》&#xff0c;意见稿规定了户用分布式光伏、一般工商业分布式光伏以及大型工商业分布式光伏的发电上网模式&#xff0c;当选择全部自发自用模式时&#x…

如何查看电脑电池性能

检查电脑电池性能的方法如下&#xff1a; 按下winR键&#xff0c;输入cmd回车&#xff0c;进入命令行窗口 在命令行窗口输入powercfg /batteryreport 桌面双击此电脑&#xff0c;把刚刚复制的路径粘贴到文件路径栏&#xff0c;然后回车 回车后会自动用浏览器打开该报告 红…

kubernetes》》k8s》》kubectl proxy 命令后面加一个

命令后面加一个& 在Linux终端中&#xff0c;如果在命令的末尾加上一个&符号&#xff0c;这表示将这个任务放到后台去执行 kubectl proxy 官网资料 是 Kubernetes 提供的一个命令行工具&#xff0c;用于在本地和 Kubernetes API Server 之间创建一个安全的代理通道。…

网络安全运维实训室建设方案

一、网络安全运维人才需求与实训困境 在数字化时代&#xff0c;网络安全已成为国家安全、社会稳定和经济发展的重要基石。随着信息技术的飞速发展&#xff0c;网络安全威胁日益复杂多样&#xff0c;从个人隐私泄露到企业商业机密被盗&#xff0c;从关键基础设施遭受攻击到社会…

DBeaver 连接mysql报错:CLIENT_PLUGIN_AUTH is required

DBeaver 连接mysql报错&#xff1a;CLIENT_PLUGIN_AUTH is required 一、必须要看这个 >> &#xff1a;参考文献 二、补充 2.1 说明 MySQL5、6这些版本比较老&#xff0c;而DBeaver默认下载的是MySQL8的连接库&#xff0c;所以连接旧版本mysql报错&#xff1a;CLIEN…

Web3时代的数据保护挑战与应对策略

随着互联网技术的飞速发展&#xff0c;我们正步入Web3时代&#xff0c;这是一个以去中心化、用户主权和数据隐私为核心的新时代。然而&#xff0c;Web3时代也带来了前所未有的数据保护挑战。本文将探讨这些挑战&#xff0c;并提出相应的应对策略。 数据隐私挑战 在Web3时代&a…

Qwen3与MCP协议:重塑大气科学的智能研究范式

在气象研究领域&#xff0c;从海量数据的解析到复杂气候模型的构建&#xff0c;科研人员长期面临效率低、门槛高、易出错的挑战。而阿里云推出的Qwen3大模型与MCP协议的结合&#xff0c;正通过混合推理模式与标准化协同机制&#xff0c;为大气科学注入全新活力。本文将深入解析…

CppCon 2015 学习:Benchmarking C++ Code

关于性能问题与调试传统 bug&#xff08;如段错误&#xff09;之间差异的分析。以下是对这一页内容的详细解释&#xff1a; 主题&#xff1a;传统问题&#xff08;如段错误&#xff09;调试流程清晰 问题类型&#xff1a;段错误&#xff08;Segmentation Fault&#xff09; …

linux 故障处置通用流程-36计+1计

通用标准处置快速索引 编号 通 用 标 准 处 置 索 引 001 Linux操作系统标准关闭 002 Linux操作系统标准重启 003 Linux操作系统强行关闭 004 Linux操作系统强行重启 005 检查Linux操作系统CPU负载 006 查询占用CPU资源最多的进程 007 检查Linux操…

​BEV和OCC学习-3:mmdet3d 坐标系

目录 坐标系 转向角 (yaw) 的定义 框尺寸的定义 与支持的数据集的原始坐标系的关系 KITTI Waymo NuScenes Lyft ScanNet SUN RGB-D S3DIS 坐标系 坐标系 — MMDetection3D 1.4.0 文档https://mmdetection3d.readthedocs.io/zh-cn/latest/user_guides/coord_sys_tuto…

[蓝桥杯]图形排版

图形排版 题目描述 小明需要在一篇文档中加入 NN 张图片&#xff0c;其中第 ii 张图片的宽度是 WiWi​&#xff0c;高度是 HiHi​。 假设纸张的宽度是 MM&#xff0c;小明使用的文档编辑工具会用以下方式对图片进行自动排版&#xff1a; 1. 该工具会按照图片顺序&#xff0…

【Linux仓库】冯诺依曼体系结构与操作系统【进程·壹】

&#x1f31f; 各位看官好&#xff0c;我是&#xff01; &#x1f30d; Linux Linux is not Unix &#xff01; &#x1f680; 今天来学习冯诺依曼体系结构与操作系统。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c;分享给更多人哦&#xff0…

CloudFront 加速详解:AWS CDN 怎么用?

让全球访问更快速稳定&#xff0c;深入解读 AWS 的内容分发网络 在上一篇中&#xff0c;我们介绍了 Amazon S3 对象存储&#xff0c;它非常适合托管静态资源&#xff0c;比如图片、视频、网页等。但你可能遇到过这样的问题&#xff1a; “我把网站静态文件部署到了 S3&#xf…

《高级架构师》------- 考后感想

笔者来聊一下架构师考后的感想 复习备考 考前过了很多知识点&#xff0c;只是蜻蜓点水&#xff0c;没有起到复习的作用&#xff0c;即使考出来也不会&#xff0c;下次复习注意这个&#xff0c;复习到了&#xff0c;就记住&#xff0c;或者画出来&#xff0c;或者文件总结&…

【iOS】YYModel源码解析

YYModel源码解析 文章目录 YYModel源码解析前言YYModel性能优势YYModel简介YYClassInfo解析YYClassIvarInfo && objc_ivarYYClassMethodInfo && objc_methodYYClassPropertyInfo && property_tYYClassInfo && objc_class YYClassInfo的初始化细…