Linux笔记---进程:进程替换

news2025/1/23 15:03:28

1. 进程替换的概念

进程替换是指在一个正在运行的进程中,用一个新的程序替换当前进程的代码和数据,使得进程开始执行新的程序,而不是原来的程序。

这种技术通常用于在不创建新进程的情况下,改变进程的行为。

我们之前谈到过fork函数,这个函数可以启动一个子进程,子进程继承了父进程的代码和数据。

在谈到进程替换之前,我们只能通过判断fork函数的返回值id来区分父子进程,并让二者运行不同的分支。而利用进程替换技术,我们可以将子进程的代码数据完全替换为另一个程序,实现我们所期望的,父子进程完全独立为两个不同的进程。

进程替换的原理

进程替换的原理涉及到操作系统的内存管理和进程控制。当一个进程调用exec系列函数时,操作系统会将新程序的代码和数据加载到内存中,并将其与当前进程的地址空间相关联。这个过程通常涉及到以下几个步骤:

  1. 加载新程序:操作系统将新程序的可执行文件从磁盘加载到内存中。
  2. 替换代码和数据:新程序的代码和数据会替换当前进程的代码和数据段。
  3. 更新进程状态:进程的状态会被更新,以反映新程序的执行状态。
  4. 执行新程序:进程开始执行新程序的入口点,通常是main函数。

在这个过程中,进程的标识符(PID)和其他一些属性(如打开的文件描述符、环境变量等)通常会保持不变。

2. exec进程替换函数

在Linux系统中,进程替换通常通过exec系列函数来实现,该系列函数包含在头文件<unistd.h>。

这些函数包括:

  • execl:执行一个新程序,参数以列表形式给出。
    int execl(const char *pathname, const char *arg, ...);
  • execlp:执行一个新程序,参数以列表形式给出,并在环境变量PATH中搜索程序。
    int execlp(const char *file, const char *arg, ...);
  • execle:执行一个新程序,参数以列表形式给出,并提供自定义的环境变量。
    int execle(const char *pathname, const char *arg, ...);
  • execv:执行一个新程序,参数以数组形式给出。
    int execv(const char *pathname, char *const argv[]);
  • execvp:执行一个新程序,参数以数组形式给出,并在环境变量PATH中搜索程序。
    int execvp(const char *file, char *const argv[]);
  • execve:执行一个新程序,参数以数组形式给出,并提供自定义的环境变量。
    int execve(const char *pathname, char *const argv[], char *const envp[]);
  • execvpe:执行一个新程序,参数以数组形式给出,并提供自定义的环境变量。
    int execvpe(const char *file, char *const argv[], char *const envp[]);
    

这些函数的使用方式和参数传递方式略有不同,但它们的基本功能都是相同的:用新程序替换当前进程的代码和数据。

记忆技巧:

  • l(list):表示参数采用列表。
  • v(vector):参数用数组。
  • p(path):到环境变量PATH中搜索指定程序,无需完整路径(带p的函数第一个参数为file,代表可执行程序;不带p的函数第一个参数为pathname,代表完整路径)。
  • e(env) : 表示自定义环境变量,不带e的表示继承当前的环境变量。

使用示例:

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

int main()
{
    char* vector[] = {"ls", "-l", "-a", NULL};
    int id = fork();
    if(id == 0)
    {
        execvp("ls", vector);
        return 0;
    }
    int pid = wait(NULL);
    return 0;
}

 注意:传入的参数为命令行参数,也就是说在命令行要执行该程序需要输入什么,参数就传递什么,主要是不要忘记选项是从第二个参数开始的。

第一个参数传什么都不要紧,随你喜欢,但要记得传:

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

int main()
{
    char* vector[] = {"cxk", "-l", "-a", NULL};
    int id = fork();
    if(id == 0)
    {
        execvp("ls", vector);
        return 0;
    }
    int pid = wait(NULL);
    return 0;
}

execve函数

该函数相比于其他函数具有一定的特殊性,他是上述函数中唯一一个系统调用。

在命令行输入[man exec]能查到如下信息,可以看到并没有execve的存在,且这些函数都在3号手册当中:

只有单独查询execve函数时才能查到,可以看到该函数在2号手册(系统调用接口)中:

 execve函数的特殊性:

  1. 系统调用层级的基础地位
    • execveexec函数族中具有特殊的基础性地位。它是直接与系统调用接口紧密相连的函数。其他的exec系列函数(如execlexecv等)在很多情况下最终可能会调用execve来实现实际的进程替换操作。
    • 例如,在一些库函数的实现中,为了提供更方便的参数传递方式(如execl的可变参数列表形式),可能会在内部对参数进行处理后调用execve来完成进程替换的核心功能。
  2. 参数处理方式的不同
    • execve的参数包含要执行的程序文件路径、传递给新程序的命令行参数数组以及环境变量数组。这种参数形式与其他exec函数有所不同。
    • execl函数,它的参数是以可变参数列表的形式,最后以NULL结尾,这种形式在使用上有一定的便利性,但在底层实现中可能需要更多的转换工作才能与系统调用接口对接,而execve的参数形式更直接地反映了系统调用的需求。
  3. 安全和权限方面的考虑
    • 由于execve是直接进行进程替换的底层函数,在安全和权限管理方面有着重要的作用。它对可执行文件的路径、执行权限等有着严格的要求。
    • 当调用execve时,系统会根据文件的权限设置(如是否可执行、所属用户和组等)以及当前进程的权限来判断是否允许进程替换操作。这种严格的权限检查有助于保障系统的安全性。
  4. 与内核交互的特点
    • execve在与内核交互时,需要将新程序的代码和数据加载到当前进程的地址空间,同时更新进程的各种状态信息,如程序计数器、堆栈指针等。这个过程涉及到内核中的进程管理、内存管理等多个模块的协同工作。
    • 相比其他exec函数,execve在与内核的这种深度交互方面更为直接,因为其他函数可能会在调用execve之前进行一些额外的参数处理或环境设置。

 exec函数族调用关系如下:

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

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

相关文章

Linux 权限管理:用户分类、权限解读与常见问题剖析

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; &#x1f6a9;用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 目录 &#x1f4af;L…

【开源】A060-基于Spring Boot的游戏交易系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

rabbitmq 安装延时队列插件rabbitmq_delayer_message_exchange(linux centOS 7)

1.插件版本 插件地址&#xff1a;Community Plugins | RabbitMQ rabbitmq插件需要对应的版本&#xff0c;根据插件地址找到插件 rabbitmq_delayer_message_exchange 点击Releases 因为我rabbitmq客户端显示的版本是&#xff1a; 所以我选择插件版本是&#xff1a; 下载 .ez文…

elementui table滚动分页加载

文章目录 概要 简化的实现示例&#xff1a; 小结 概要 在使用 Element UI 的 Table 组件时&#xff0c;如果需要实现滚动分页加载的功能&#xff0c;可以通过监听 Table 的滚动事件来动态加载更多数据。 简化的实现示例&#xff1a; <template><el-table ref"…

书生浦语第四期--基础岛-第五关

文章目录 学习使用Xtuner微调大模型开始微调检查hf文件夹检查meraged文件夹启用WebUI 对话查看效果 学习使用Xtuner微调大模型 开始微调 检查hf文件夹 检查meraged文件夹 启用WebUI 对话 查看效果

基于Transformer的编码器-解码器图像描述模型在AMD GPU上的应用

Transformer based Encoder-Decoder models for image-captioning on AMD GPUs — ROCm Blogs 图像描述&#xff0c;即基于生成式人工智能&#xff08;GenAI&#xff09;自动生成简洁的图像文本描述&#xff0c;在现实世界中有着非常重要的应用。例如&#xff0c;图像描述可以为…

解决Jupyter Notebook无法转化为Pdf的问题(基于Typora非常实用)

笔者在完成各项作业和做笔记时&#xff0c;经常用到jupyter notebook&#xff1b;其因为可以同时运行python并提供格式化的数字公式的输入方式&#xff0c;得到了广大用户的喜爱。 当我们想要将.ipynb文件导出为pdf时&#xff0c;有两种常用方法。 1.Ctrlp 2.通过File ->…

ROS-plotjuggler的使用

简介 一个基于Qt的应用程序&#xff0c;允许用户加载、搜索和打印数据。通常对rosbag画图的辅助工具使用。 使用方法 启动 rosrun plotjuggler plotjuggler打开界面左上角&#xff0c;加载并选择相应数据 如果要用两个数据绘图&#xff0c;则ctrl选中后右键拖入

【笔记】离散数学 1-3 章

1. 数理逻辑 1.1 命题逻辑的基本概念 1.1.1 命题的概念 命题&#xff08;Proposition&#xff09;&#xff1a;是一个陈述句&#xff0c;它要么是真的&#xff08;true&#xff09;&#xff0c;要么是假的&#xff08;false&#xff09;&#xff0c;但不能同时为真和假。例如…

在服务器上实现本地python文件的依赖

1、在python中&#xff0c;一个python文件就可以视为一个模块进行导入 2、使用import 导入时&#xff0c;若使用pip 下载过可以直接导入 3、假如是自己写的同项目中的文件会去sys.path 中查找 比如说 我现在 test 下有一个 python文件 运行 下面的代码 打印的数据如上图所示p…

解决python 使用pip 安装模块时遇到的错误SSL: CERTIFICATE_VERIFY_FAILED

最近有一个使用python 2.7.* 使用requests模块的需求,在安装的过程中遇到了一个问题&#xff0c;在这里分享给大家&#xff01; 安装requests命令如下 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests 遗憾的是&#xff0c;报错了 Collecting requests …

蓝桥杯准备训练(lesson2 ,c++)

3.1 字符型 char //character的缩写在键盘上可以敲出各种字符&#xff0c;如&#xff1a; a &#xff0c; q &#xff0c; &#xff0c; # 等&#xff0c;这些符号都被称为字符&#xff0c;字符是⽤单引号括 起来的&#xff0c;如&#xff1a; ‘a’ &#xff0c; ‘b’ &…

opencvocr识别手机摄像头拍摄的指定区域文字,文字符合规则就语音报警

安装python&#xff0c;pycharm&#xff0c;自行安装。 Python下安装OpenCv 2.1 打开cmd,先安装opencv-python pip install opencv-python --user -i https://pypi.tuna.tsinghua.edu.cn/simple2.2 再安装opencv-contrib-python pip install opencv-contrib-python --user …

LabVIEW中“this VI‘s owning library is missing”错误及解决

问题描述 当加载或打开一个VI时&#xff0c;如果其所属的项目库未加载到内存&#xff0c;LabVIEW将提示错误&#xff1a;“this VIs owning library is missing”&#xff08;该VI的所属库不存在&#xff09;。 该问题通常发生在以下情况下&#xff1a; 项目库文件丢失或路径…

【效果】回到顶部功能实现

实现效果&#xff1a; 相关代码&#xff1a; <template><div class"cats" :style"{ top: catsTop }" ref"cats" click"catTop"></div> </template> 样式&#xff1a; /* 回到顶部 - 小猫咪 */ .cats {posi…

算法第一弹-----双指针

目录 1.移动零 2.复写零 3.快乐数 4.盛水最多的容器 5.有效三角形的个数 6.查找总价值为目标值的两个商品 7.三数之和 8.四数之和 双指针通常是指在解决问题时&#xff0c;同时使用两个指针&#xff08;变量&#xff0c;常用来指向数组、链表等数据结构中的元素位置&am…

计算机网络期末复习-part1-概述

1、互联网的组成 互联网由两大块组成。 1、边沿部分&#xff1a;由所有连接在互联网上的主机组成&#xff0c;是用户直接使用的部分。 2、核心部分&#xff0c;由大量网络和路由器组成&#xff0c;为边缘部分提供服务。 2、数据传送阶段的三种交换方式的主要特点 1、电路交…

【Linux系统编程】——理解冯诺依曼体系结构

文章目录 冯诺依曼体系结构硬件当代计算机是性价比的产物冯诺依曼的存储冯诺依曼的数据流动步骤冯诺依曼结构总结 冯诺依曼体系结构硬件 下面是整个冯诺依曼体系结构 冯诺依曼结构&#xff08;Von Neumann Architecture&#xff09;是现代计算机的基本结构之一&#xff0c;由数…

微信创建小程序码 - 数量不受限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…

JDK8 下载与安装

下载安装包 官网下载 官网 找到适合的版本: 网盘下载 网盘链接 提取码: 6666 下载得到的安装包: 安装步骤 双击安装包开始安装. 安装路径不要有中文或者特殊符号如空格等. 更改安装路径: 跳出一个页面, 安装公共 JRE: 安装完成: 安装目录: 安装的公共 JRE: JDK 里面的 JR…