【进程替换】多进程程序替换原理 | 进程程序替换函数 | execlexecv | execlpexecvp

目录

多进程程序替换

多进程程序替换原理

进程程序替换函数详解

execl&execv

execlp&execvp

execle&execvpe 

execve


多进程程序替换

  • 我们想要进程替换的同时不影响旧的进程(使用多进程版)
  • fork创建子进程,让子进程去替换执行新程序(因为替换进程本身不会创建新的进程)
  • 父进程依旧执行旧的进程,且等待子进程(非阻塞等待)
  • 父进程只等待子进程(阻塞等待)
  • 子进程可以替换系统指令,也可以替换我们自己的程序,只要是一个可执行程序都可以替换。
  • 两全其美:既让子进程完成了任务,又不能让父进程受到影响

说明fork创建子进程完成任务:

  • 让子进程执行父进程代码的一部分
  • 让子进程执行一个全新的程序
  • 基于进程间的独立性原则。
  • fork创建的子进程默认在不修改的前提下,父子进程的数据和代码时共享的。
  • 子进程发生了进程替换,相当于发生写入,发生了写时拷贝。
  • 执行一个全新的程序,父子进程是独立的,所以不仅数据要写时拷贝,代码也要发生写时拷贝。只要程序替换成功了,父子进程无论是代码/数据在内核数据结构层面上,数据代码层面上彻底分开了。

子进程发生程序替换:

  • 共享父进程的数据代码
  • 暂停了把新程序的代码和数据从磁盘到内存的加载/写入
  • 发生写时拷贝
  • 开启加载/写入(页表的权限会改变)
  • 重新建立映射关系
 1: testexec.c 1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     execl("/usr/bin/ls","ls","-l","-a",NULL);                                                            16     exit(1);17   }18   //father19   int status = 0;20   pid_t rid = waitpid(id,&status,0);21   if(rid > 0)22   {23     printf("father wait success!,child exit code: %d\n",WEXITSTATUS(status));24   }25   printf("testexec... end!\n");26   return 0;27 }//测试失败
execl("/usr/bin/lsss","lsss","-l","-a",NULL);    

【测试成功】细看退出码

【测试失败】细看退出码

 

多进程程序替换原理

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

进程程序替换函数详解

前篇粗略的介绍了下替换函数,现在一个一个详解介绍。使用所有的替换方法,并且认识函数参数的含义

  • OS中默认进程程序替换函数有6个库函数和1个系统调用函数。
  • 其实有六种以exec开头的函数,统称exec函数
#include <unistd.h>`
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
//系统调用函数
int execve(const char *path, char *const argv[], char *const envp[]);

execl&execv

  • l:list列表
  • int execl(const char *path, const char *arg, ...); 
  • path:表示替换程序的路径(绝对/相对路径均可)☞☞怎样找到可执行程序需告知
  • arg:可变参数,在命令行中怎么执行,就怎么传参。☞☞你想怎么执行
  • arg形成命令行参数表传给ls指令的可执行程序main函数接收使用
  • 注意❗最后必须以NULL结尾

  • V:Vector动态数组
  • int execv(const char *path, char *const argv[ ]);
  • path:表示替换程序的路径(绝对/相对路径均可)☞☞怎样找到可执行程序需告知
  • argv:指针数组(可变参数与其一个一个传参,直接放到数组里面,传数组即可)(带入命令行参数表)
  • argv被当作命令行参数表传给ls指令的可执行程序main函数接收使用
  • 字符串的类型是const char*变成char*需要强转
  • 注意❗最后必须以NULL结尾
  • 这两个函数只是在传参形式上发生了变化,实际上没有区别。
  1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     execl("/usr/bin/ls","ls","-l","-a",NULL);  //❗                                                          16     exit(1);17   }//1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     char *const argv[] =16     {17       (char*)"ls",18       (char*)"-l",                                                                                       19       (char*)"-a",20       (char*)"--color",21       NULL22     };23     execv("/usr/bin/ls",argv); //❗24     exit(1);25   }26   //father27   int status = 0;28   pid_t rid = waitpid(id,&status,0);29   if(rid > 0)30   {31     printf("father wait success!,child exit code: %d\n",WEXITSTATUS(status));32   }33   printf("testexec... end!\n");34   return 0;                                                                                              35 }

execlp&execvp

  • p:环境变量PATH
  • 带p的函数不用带绝对/相对路径传递参数了,表示用户可以不传递替换程序的路径(但是要传递可执行程序的文件名file)
  • 用户可以不传递要执行的文件路径(文件名要传),直接告诉exec*,我要执行谁即可。
  • p:查找这个程序,系统会自动在环境变量PATH中进行查找。
  • int execlp(const char *file, const char *arg, ...);
  • int execvp(const char *file, char *const argv[ ]);
 1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     execlp("ls","ls","-l","-a",NULL);  //❗                                                          16     exit(1);17   }//1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     char *const argv[] =16     {17       (char*)"ls",18       (char*)"-l",                                                                                       19       (char*)"-a",20       (char*)"--color",21       NULL22     };23     execvp("ls",argv); //❗24     exit(1);25   }26   //father27   int status = 0;28   pid_t rid = waitpid(id,&status,0);29   if(rid > 0)30   {31     printf("father wait success!,child exit code: %d\n",WEXITSTATUS(status));32   }33   printf("testexec... end!\n");34   return 0;                                                                                              35 }

execle&execvpe 

  • e:environment环境变量
  • int execle(const char *path, const char *arg, ...,char *const envp[ ]);
  • int execvpe(const char *file, char *const argv[ ],char *const envp[ ]);

  • bash有环境变量,也可以获取命令行参数
  • bash创建父进程
  • fork创建子进程
  • 通过exec*等函数将环境变量表和命令行参数表交给可执行程序
  • 子进程运行起来,并使用两张表

execve

🙂感谢大家的阅读,若有错误和不足,欢迎指正。 下篇收尾❗

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

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

相关文章

2008NOIP普及组真题 4. 立体图

线上OJ&#xff1a; 一本通-1977&#xff1a;【08NOIP普及组】立体图 核心思想&#xff1a; 本题采用模拟方法一个一个画小方块&#xff08;虽然画的是立体空间的积木&#xff0c;但本质还是在二维平面上画图形&#xff09; 本题的难点在于&#xff1a; 1、如何确定二维平面画…

tengine-docker镜像制作

1.下载 wget https://tengine.taobao.org/download/tengine-3.0.0.tar.gz 或者直接下载这个包括下边两个配置文件了 https://download.csdn.net/download/cyw8998/89286114 2.编辑nginx.conf文件 #####user nobody; worker_processes 1;#error_log logs/error.log; #er…

浅析扩散模型与图像生成【应用篇】(二十三)——Imagic

23. Imagic: Text-Based Real Image Editing with Diffusion Models 该文提出一种基于文本的真实图像编辑方法&#xff0c;能够根据纯文本提示&#xff0c;实现复杂的图像编辑任务&#xff0c;如改变一个或多个物体的位姿和组成&#xff0c;并且保持其他特征不变。相比于其他文…

c语言题库之序列合并

文章目录 前言C语言题目&#xff1a;分析1. 合并逻辑2.图解合并逻辑 代码实现注意事项总结思考 前言 在编程中&#xff0c;我们经常遇到需要将两个有序序列合并为一个有序序列的问题。下面&#xff0c;我们就来详细探讨一下如何解决这个问题&#xff0c;包括输入处理、合并逻辑…

python 根据网址和关键词批量下载影像

最近用到了GLASS的LAI产品&#xff0c;但这个产品的文件夹分得很细&#xff0c;我需要的影像又有8个瓦片&#xff0c;一个一个点击很麻烦&#xff0c;于是探索了批量下载的方法 一、下载1幅 import requests import re import os import requests import re# 网页URLurl &…

深入理解Java HashSet类及其实现原理

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

Java中什么是多态?多态的实现原理是什么?多态在Java中的意思实现方式是什么?多态在框架设计中有什么作用应用场景?

什么是多态&#xff1f; 多态是面向对象编程中的一个重要概念&#xff0c;它允许不同类的对象对同一消息做出响应。在 Java中&#xff0c;多态通常体现为子类对象可以替代父类对象的特性。这意味着你可以使用父类的引用来引用子类的对象。 多态的实现原理&#xff1a; 多态的…

如何在 CentOS 上安装并配置 Redis

如何在 CentOS 上安装并配置 Redis 但是太阳&#xff0c;他每时每刻都是夕阳也都是旭日。当他熄灭着走下山去收尽苍凉残照之际&#xff0c;正是他在另一面燃烧着爬上山巅散烈烈朝晖之时。 ——史铁生 环境准备 本教程将在 CentOS 7 或 CentOS 8 上进行。确保你的系统已更新到最…

Channel实现Flutter与原生平台之间的双向通信

文章目录 &#xff08;一&#xff09;通过MessageChannel实现Flutter与原生平台之间的双向通信Flutter端实现MessageChannel通信步骤&#xff1a;Android端实现MessageChannel通信步骤&#xff1a; &#xff08;二&#xff09;通过MethodChannel实现Flutter与原生平台之间的双向…

uniapp/微信小程序实现加入购物车点击添加飞到购物车动画

1、预期效果 2、实现思路 每次点击添加按钮时&#xff0c;往该按钮上方添加一个悬浮元素&#xff0c;通过位移动画将元素移到目标位置。 1. 为每个点击元素设置不同的class&#xff0c;才能通过uni.createSelectorQuery来获取每个元素的节点信息&#xff1b; 2. 添加一个与…

c++:(map和set的底层简单版本,红黑树和AVL树的基础) 二叉搜索树(BST)底层和模拟实现

文章目录 二叉搜索树的概念二叉搜索树的操作二叉搜索树的查找find 二叉搜索树的模拟实现构造节点insertfinderase(细节巨多,面试可能会考)a.叶子节点b.有一个孩子左孩子右孩子 c.有两个孩子注意: erase代码 中序遍历 二叉搜索树的应用k模型k模型模拟实现的总代码 k-value模型k-…

7-Zip命令行调用命令收集(20个)

列出压缩文件的内容: 7z l archive.7z 解压压缩文件到当前目录: 7z x archive.7z 解压压缩文件到指定目录: 7z x archive.7z -o"C:\path\to\extract" 创建新的压缩文件 (添加到archive.7z): 7z a archive.7z file_to_compress 创建包含多个文件的压缩文件: 7z a arc…

【JVM】了解JVM规范中的虚拟机结构

目录 JVM规范的主要内容 1&#xff09;字节码指令集(相当于中央处理器CPU) JVM指令分类 2&#xff09;Class文件的格式 3&#xff09;数据类型和值 4&#xff09;运行时数据区 5&#xff09;栈帧 6&#xff09;特殊方法 7&#xff09;类库 JVM规范的主要内容 1&#…

Vue3+ElementPlus+TS开发业务功能的问题汇总(持续更新)

1.开发表单弹框功能时遇到两个问题&#xff1a;加入了校验规则后&#xff0c;无论下拉框是否选择数据下面的红色提示都会触发显示不会自动隐藏 &#xff1b; 另外&#xff0c;新增的功能在提交后数据无法重置&#xff0c;这种在修改时可能会出现&#xff0c;但新增正常情况是不…

走进C++:C到C++的过渡

目录 什么是C呢&#xff1f; C的发展史 多了一些吃前来很香的“语法糖”。 语法糖一&#xff1a;命名空间 命名空间有个强大的功能 如何使用 语法糖二&#xff1a;缺省参数 语法糖三&#xff1a;函数重载 语法糖四&#xff1a;引用 引用传参 引用返回 引用和…

【ZZULIOJ】1100: 求组合数(函数专题)(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy 提示 code 题目描述 马上要举办新生程序设计竞赛了&#xff0c;与以往不同的是&#xff0c;本次比赛以班为单位&#xff0c;为了全面衡量一个班级的整体水平&#xff0c;要求从一个班的m位同学中任选k位同学代表本…

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制&#xff08;2&#xff09; 计算fps帧率 用 adb shell dumpsys SurfaceFlinger --list 查询当前的SurfaceView&#xff0c;然后有好多行&#xff0c;再把要查询的行内容完整的传给 ad…

算法训练Day35 | ● 343. 整数拆分 ● 96.不同的二叉搜索树

343. 整数拆分 class Solution { public:int integerBreak(int n) {vector<int> dp(n1, 0);dp[2] 1;for(int i3; i<n1; i){for(int j 1; j<i/2; j){dp[i] max(dp[i], max(j*(i-j), j*dp[i-j]));}}return dp[n];} };参考文章&#xff1a;代码随想录-343. 整数拆分…

找不到msvcp140.dll无法执行代码的原因分析及修复方法

当用户在尝试运行某些应用程序或游戏时&#xff0c;可能会遇到系统弹出错误提示&#xff0c;显示“找不到msvcp140.dll无法执行代码”这一错误信息&#xff0c;它会导致程序无法正常启动。为了解决这个问题&#xff0c;我经过多次尝试和总结&#xff0c;找到了以下五种解决方法…

hadoop启动后没有namenode,datanode等解决方法

之前用的是虚拟机&#xff0c;在虚拟机上安装的hadoop&#xff0c;但是后来&#xff0c;电脑恢复出厂设置了&#xff0c;什么都重新开始。就在本地安装 Linux 子系统。 但是&#xff0c;有时候start-dfs.sh后&#xff0c;jps出现错误。 像这种拒绝连接 解决办法就是如下&…