当前位置: 首页 > news >正文

【Linux】详解进程程序替换

一、替换原理

        用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。程序替换所做的本质工作就是将代码和数据加载到内存。

        替换系统命令时命令行怎么写,参数就怎么传,参数以NULL结尾程序替换一旦成功,exec*后序的代码不再执行。因为原程序的数据和代码被替换掉了。exec*程序替换接口只有失败返回值,没有成功返回值。

二、子进程进行程序替换

        通过子进程进行程序替换可以让子进程帮我们去做一部分工作,而且子进程发生程序替换不会影响父进程执行,因为替换时代码和数据会发生写时拷贝。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{pid_t id = fork();if(id == 0){execl("/usr/bin/ls", "ls", "-l", NULL);exit(0);}pid_t rid = waitpid(id, NULL, 0);printf("wait success!\n");return 0;
}

2.1、让子进程执行我自己的程序

        我自己写了一个C++程序,向替换子进程帮我跑一下:

//C++程序
#include <iostream>
using namespace std;int main()
{cout << "Hello Linux!" << endl;cout << "Hello Linux!" << endl;cout << "Hello Linux!" << endl;cout << "Hello Linux!" << endl;return 0;
}

 C程序:

//让子进程执行我自己写的程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{pid_t id = fork();if(id == 0){execl("./mytest", "./mytest", NULL);exit(0);}pid_t rid= waitpid(id, NULL, 0);if(rid > 0)printf("wait success!\n");return 0;
}

        执行结果如下,证明了我们不仅仅可以替换子进程执行系统程序,还可以替换子进程执行我们的程序。 无论是什么语言,只要能在Linux系统下跑,都可以用exec系列的接口进行程序替换,exec系列的接口只认二进制代码和数据。

三、各种exec接口

 其它六个接口在底层都封装了execve系统调用接口。

3.1、execlp 

        exec接口中,l意为list,表示参数列表,v意为vector,就指的是数组名字中带p的这个p指的是PATH,也就是说你不用告诉系统,程序在哪里,只要告诉我名字就行,系统会自动到你这个进程的PATH环境变量中所保存的路径中寻找。execlp只有第一个参数和execl不同,其余参数都相同。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{pid_t id = fork();if(id == 0){execlp("ls", "ls", "-l", NULL);exit(0);}pid_t rid = waitpid(id, NULL, 0);printf("wait success!\n");return 0;
}

3.2、execv/execvp

        execv的用法与execl的用法大致相同,只不过将execl后面的可变参数列表换成一个指针数组。execvp也只是将execv前面的路径换成程序名而已。不过这里要强调的是:不要忘了路径最前面的那一个斜杠,还有数组的结束标志是NULL,一定要在数组的最后加上NULL

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{pid_t id = fork();if(id == 0){char* argv[] = {"ls", "-l", "-a", NULL};//execvp("ls", argv);execv("/usr/bin/ls", argv);exit(0);}pid_t rid= waitpid(id, NULL, 0);if(rid > 0)printf("wait success!\n");return 0;
}

3.3、execle/execvpe/execve

        程序替换不会替换环境变量数据可以通过地址空间继承的方法,让子进程拿到父进程的所有环境变量。如果我们想传递全新的环境变量表给子进程,就要使用带e的程序替换接口。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{pid_t id = fork();if(id == 0){char* env[] ={"aaa=bbbbbbbbbbbbbbbb", NULL};execle("./mytest", "./mytest",NULL,  env);exit(0);}pid_t rid= waitpid(id, NULL, 0);if(rid > 0)printf("wait success!\n");return 0;
}

相关文章:

【Linux】详解进程程序替换

一、替换原理 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支)&#xff0c;子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时&#xff0c;该进程的用户空间代码和数据完全被新程序替换&#xff0c;从新程序的启动例程开始执…...

vue中使用jsmind生成脑图

项目部分参数&#xff1a; vue&#xff1a;2.6.10 node:16.20.0 1、使用命令行安装jsmind&#xff1a; npm i jsmind -S 2、在文件中引入jsmind&#xff0c;并编写渲染jsmind的代码&#xff1a;&#xff1a; <template><!-- jsmind容器 --><divid"jsmi…...

yarn按包的时候报错 ../../../package.json: No license field

运行 yarn config list 然后运行 yarn config set strict-ssl false 之后yarn就成功了...

【Python从入门到进阶】51、电影天堂网站多页面下载实战

接上篇《50、当当网Scrapy项目实战&#xff08;三&#xff09;》 上一篇我们讲解了使用Scrapy框架在当当网抓取多页书籍数据的效果&#xff0c;本篇我们来抓取电影天堂网站的数据&#xff0c;同样采用Scrapy框架多页面下载的模式来实现。 一、抓取需求 打开电影天堂网站&…...

苹果CMS影视APP源码,二开版本带视频教程

编译app教程 工具下载&#xff1a;Android Studio 官网地址&#xff1a;https://developer.android.google.cn/studio/ 环境设置&#xff1a; 设置中文&#xff1a;https://blog.csdn.net/qq_37131111/article/details/131492844 汉化包找最新的下载就行了&#xff0c;随便下载…...

Zigbee技术在智能农业领域的应用研究

Zigbee技术在智能农业领域的应用研究 **摘要&#xff1a;**随着现代信息技术的飞速发展&#xff0c;智能农业已成为当今农业发展的新趋势。Zigbee技术作为一种低功耗、低成本的无线通信技术&#xff0c;在智能农业领域具有广泛的应用前景。本文深入分析了Zigbee技术的原理和特…...

Spring Cloud Gateway 中GET请求能正常访问,POST请求出现Unable to handle DataBuffer

报错信息如下&#xff1a; java.lang.IllegalArgumentException: Unable to handle DataBuffer of type class org.springframework.http.server.reactive.UndertowServerHttpRequest$UndertowDataBufferat org.springframework.cloud.gateway.filter.NettyRoutingFilter.getB…...

什么是git? 初步认识git 如何使用git

Git是什么&#xff1f; Git 是分布式版本控制系统&#xff0c;可以有效&#xff0c;高速地处理从很小到非常大地项目版本管理&#xff0c;分布式相比于集中式的最大区别在于开发者可以提交到本地&#xff0c;每个开发者可以通过克隆&#xff0c;在本地机器上拷贝一个完整的Git …...

Douyin视频详情数据API接口(视频详情,评论)

抖音官方并没有直接提供公开的视频详情数据采集API接口给普通用户或第三方开发者。抖音的数据采集通常受到严格的限制&#xff0c;以保护用户隐私和平台安全。 请求示例&#xff0c;API接口接入Anzexi58 如果您需要获取抖音视频详情数据&#xff0c;包括评论、点赞等&#xff…...

MySQL 索引:索引为什么使用 B+树?

Hash 索引不支持顺序和范围查询&#xff1b; 二叉查找树(BST)&#xff1a;解决了排序的问题&#xff0c;极端情况下可能会退化成线性链表&#xff0c;查询效率急剧下降&#xff1b; 平衡二叉树(AVL) &#xff1a;通过旋转解决了平衡的问题&#xff0c;但是旋转操作效率太低&am…...

2024年第四届天府杯全国大学生数学建模竞赛B题思路

B题&#xff1a;新质生产力引领下的企业生产与发展策略优化 问题背景 随着技术的飞速发展&#xff0c;新质生产力如人工智能、大数据分析、物联网等技术被广泛应用于生产和服务过程中&#xff0c;极大地提高了生产效率和产品质量&#xff0c;改变了传统的生产与经营模式。一家…...

c++部分题

const关键字与宏定义的区别是什么&#xff1f; const关键字和宏定义在功能上有相似之处&#xff0c;但在实现和使用上有很大的区别。 作用域和类型安全性&#xff1a; const关键字定义的常量具有作用域和类型安全性。它们的作用域仅限于声明它们的块&#xff0c;并且在编译时会…...

验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给定一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否则&#…...

vue2高德地图选点

<template><el-dialog :title"!dataForm.id ? 新建 : isDetail ? 详情 : 编辑" :close-on-click-modal"false" :visible.sync"show" class"rv-dialog rv-dialog_center" lock-scroll width"74%" :before-close&q…...

Gitflow:一种依据 Git 构建的分支管理工作流程模式

文章目录 前言Gitflow 背景Gitflow 中的分支模型Gitflow 的版本号管理简单模拟 Gitflow 工作流 前言 Gitflow 工作流是一种版本控制流程&#xff0c;主要适用于较大规模的团队。这个流程在团队中进行合作时可以避免冲突&#xff0c;并能快速地完成项目&#xff0c;因此在很多软…...

利用云手机技术,开拓海外社交市场

近年来&#xff0c;随着科技的不断进步&#xff0c;云手机技术逐渐在海外社交营销领域崭露头角。其灵活性、成本效益和全球性特征使其成为海外社交营销的利器。那么&#xff0c;究竟云手机在海外社交营销中扮演了怎样的角色呢&#xff1f; 首先&#xff0c;云手机技术能够消除地…...

脚本实现Ubuntu设置屏幕无人操作,自动黑屏

使用 xrandr 命令可以实现对屏幕的控制&#xff0c;包括调整分辨率、旋转屏幕以及关闭屏幕等。要实现 Ubuntu 设置屏幕在无人操作一段时间后自动黑屏&#xff0c;非待机&#xff0c;并黑屏后点击触摸屏可以唤醒屏幕&#xff0c;可以借助 xrandr 命令来实现。 首先&#xff0c;…...

16.JRE和JDK

程序员在编写代码的时候其实是需要一些环境&#xff0c;例如我们之前写的HelloWorld。我们需要的东西有JVM、核心类库、开发工具。 1、JVM&#xff08;Java Virtual Machine&#xff09;&#xff1a;Java虚拟机&#xff0c;真正运行Java程序的地方。没有虚拟机&#xff0c;代码…...

C++从入门到精通——命名空间

命名空间 前言一、命名空间引例什么是命名空间 二、命名空间定义正常的命名空间定义嵌套的命名空间多个相同名称的命名空间 三、命名空间使用加命名空间名称及作用域限定符使用using将命名空间中某个成员引入使用using namespace 命名空间名称引用引用命名空间和引用头文件有什…...

JAVA面试大全之JAVA新特性篇

目录 1、Java 8特性 1.1、什么是函数式编程?Lambda表达式? 1.2、Stream中常用方法? 1.3、什么是FunctionalInterface? 1.4、如何自定义函数接口?...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...