七、进程程序替换
文章目录
- 一、进程程序替换
- (一)概念
- (二)为什么程序替换
- (三)程序替换的原理
- (四)如何进行程序替换
- 1. execl
- 2. 引入进程创建——子进程执行程序替换,会不会影响父进程呢?
- (五)大量的测试各种不同的接口
- 1.命名理解 (带v和带l的)
- 2.记忆技巧
- 3.带e和带p
- (六)具体接口说明
- 1.execv
- 2.execlp
- 3.execvp
- 4.execle
- 二、模拟实现shell
- 三、内建命令——以chdir为例
一、进程程序替换
(一)概念
子进程执行的是父进程的代码片段,如果我们想让创建出来的子进程,执行全新的程序呢?
需要用到:进程的程序替换!
(二)为什么程序替换
我们一般在服务器设计(linux编程)的时候,往往需要子进程干两件种类事情!
- 让子进程执行父进程的代码片段(服务器代码)
- 让子进程执行磁盘中一个全新的程序(shell,想让客户端执行对应的程序,通过我们的进程,执行其他人写的进程代码等等),c/c++ ->c/c++/Python/Shell/Php/Java…
(三)程序替换的原理
- 将磁盘中的程序,加载入内存结构
- 重新建立页表映射,谁执行程序替换,就重新建立谁的映射(子进程)
效果:让我们的父进程和子进程彻底分离,并让子进程执行一个全新的程序!
这个过程有没有创建新的进程呢?
没有,子进程的PCB等结构并未改变,只是改变的页表映射关系。
程序替换成功后,运行完新程序,则程序直接退出;程序替换成功后,原进程没有退出,使用原进程运行新程序
我们只能调用接口,为什么呢?
因为这个过程实际上是把数据从一个硬件搬到另一个硬件的操作,这个操作只能由OS操作系统完成
(四)如何进行程序替换
man execl 查看进行程序替换的函数:
我们如果要执行一个全新的程序,我们需要做几件事情呢?
1.程序本质就是一个磁盘上的文件,所以我们需要先找到这个程序在哪里
2.程序可能携带选项进行执行(也可以不携带),然后告诉OS,我要怎么执行这个程序?(要不要带选项)
命令行怎么写(ls -l -a), 这个参数就怎么填"ls",“-l”,“-a”,最后必须是NULL,标识参数传递完毕[如何执行程序的]
#include <unistd.h>extern char **environ;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[]);
1. execl
makefile
myexec:myexec.cg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f myexec
myexec.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>
#include<sys/types.h>
#include<sys/wait.h>int main(int argc,char *argv[]) {printf("process is running...\n");pid_t id = fork();assert(id != -1);if (id == 0) {sleep(1);printf("我是一个进程,我的pid是:%d\n",getpid());// 执行ls -l -a 命令//execl("/usr/bin/ls","ls","-l","-a",NULL); // 这里有两个ls, 重复吗?不重复,一个是告诉系统我要执行谁?一个是告诉系统,我想怎么执行// 执行top命令execl("/usr/bin/top","top",NULL); printf("我执行完毕了,我的pid是:%d\n",getpid()); // 执行完以上的代码,我们发现一个问题!!// 最后一句代码为什么没有被打印出来呢!!!}return 0;
}
因为进程一旦替换成功,是将当前进程的代码和数据全部替换了!!!
后面的printf是代码吗??有没有被替换呢??当然,已经早就被替换了!!该代码不存在了!!
所以这个程序替换函数,用不用判断返回值?为什么?
答:不用判断返回值,因为只要成功了,就不会有返回值execl,一旦替换成功,是将当前进程的所有代码和数据全部替换了,execl就直接执行ls命令的代码去了。。而失败的时候,必然会继续向后执行!!最多通过返回值得到什么原因导致的替换失败!
2. 引入进程创建——子进程执行程序替换,会不会影响父进程呢?
子进程执行程序替换,会不会影响父进程呢? ?
不会,因为进程具有独立性。
为什么,如何做到的? ?数据层面发生写时拷贝!当程序替换的时候,我们可以理解成为:代码和数据都发生了写时拷贝完成父子的分离!
(五)大量的测试各种不同的接口
1.命名理解 (带v和带l的)
这些函数原型看起来很容易混,但只要掌握了规律就很好记。l(list) : 表示参数采用列表v(vector) : 参数用数组p(path) : 有p自动搜索环境变量PATHe(env) : 表示自己维护环境变量
2.记忆技巧
execl结尾 l 为list,列表传参——>可变参数包,一个一个传。execv结尾 v 为vector,数组传参——>传的是指针数组。
3.带e和带p
带e的都是可以传环境变量的(execle,execvpe)但是会覆盖系统原有的环境变量,把自己传的环境变量交给进程;
不带e是默认继承系统的环境变量;带p的都是可以自带路径的,直接传命令名称即可(execlp,execvp,execvpe)
(六)具体接口说明
1.execv
int execv(const char *path, char *const argv[]);
path 依然是程序的路径,参数 argv[] 是存着要实现指令的指针数组
char *const argv_[] = {"ls","-a","-l","--color=auto",NULL
};
2.execlp
int execlp(const char *file, const char *arg, ...); 带p的就传程序名即可file:要执行的程序。执行指令的时候,默认的搜索路径,在哪里搜索呢?在环境变量PATH
命名带p的,可以不带路径,只说出你要执行哪一个程序即可!execlp("ls","ls", "-a", "-1 ",NULL)
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>
#include<sys/types.h>
#include<sys/wait.h>int main(int argc,char *argv[]) {printf("process is running...\n");pid_t id = fork();assert(id != -1);if (id == 0) {sleep(1);printf("我是一个进程,我的pid是:%d\n",getpid());//execl("/usr/bin/ls","ls","-l","-a",NULL); // 这里有两个ls, 重复吗?不重复,一个是告诉系统我要执行谁?一个是告诉系统,我想怎么执行// 执行top命令char *const argv_[]={(char*)"ls",(char*)"-a",(char*)"-l",NULL};//execl("/usr/bin/top","top",NULL); execlp("ls","ls","-a","-l",NULL);//这里出现了两个ls,含义一样吗?不一样!exit(1); //execvp("ls", argv_);printf("我执行完毕了,我的pid是:%d\n",getpid()); // 执行完以上的代码,我们发现一个问题!!// 最后一句代码为什么没有被打印出来呢!!!}int status = 0;int ret = waitpid(id,&status,0);if(ret == id){sleep(2);printf("父进程等待成功!\n");}return 0;
}
3.execvp
int execvp(const char *file, char *const argv[]);
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>
#include<sys/types.h>
#include<sys/wait.h>int main(int argc,char *argv[]) {printf("process is running...\n");pid_t id = fork();assert(id != -1);if (id == 0) {sleep(1);printf("我是一个进程,我的pid是:%d\n",getpid());//execl("/usr/bin/ls","ls","-l","-a",NULL); // 这里有两个ls, 重复吗?不重复,一个是告诉系统我要执行谁?一个是告诉系统,我想怎么执行// 执行top命令char *const argv_[]={(char*)"ls",(char*)"-a",(char*)"-l",NULL};//execl("/usr/bin/top","top",NULL); //execlp("ls","ls","-a","-l",NULL);//这里出现了两个ls,含义一样吗?不一样!exit(1); execvp("ls", argv_);printf("我执行完毕了,我的pid是:%d\n",getpid()); // 执行完以上的代码,我们发现一个问题!!// 最后一句代码为什么没有被打印出来呢!!!}// 父进程int status = 0;int ret = waitpid(id,&status,0);if(ret == id){sleep(2);printf("父进程等待成功!\n");}return 0;
}
4.execle
int execle(const char *path, const char *arg,..., char * const envp[]);
这里的前几个接口都非常熟悉了,这里最后一个接口叫做环境变量。那么为什么要有这个接口呢?
说到环境变量之前我们先来看一下这个问题,我们刚刚提到过,进程替换可以让我们执行其他语言写的程序,那么我们怎么来执行呢?(我们使用execl 函数来调用)
我们现在的目标是想用我们写的myexec.c把mycmd.cpp调用起来,那么怎么来用呢?
myexec.c
我们当前使用的是绝对路径来调用我的mycmd程序!
当然我们也可以使用相对路径来调用。
相对路径调用——
makefile
.PHONY:all
all: mybin myexec
mybin:mybin.cg++ -o $@ $^ -std=c++11
myexec:myexec.cg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f myexec mybin
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>int main()
{printf("我是一个进程,我的pid是:%d\n",getpid());pid_t id=fork(); if(id==0){//childprintf("我是子进程,我的pid是:%d\n",getpid());execl("./mycmd","mycmd",NULL);exit(1);}//一定是父进程int status=0;int ret=waitpid(id,&status,0);if(ret==id){sleep(2);printf("父进程等待成功!\n");}return 0;
}
为什么会有这么多接口?——因为要适配应用场景。
execve为什么是单独的?——实际上,只有 execve是系统调用,其他都是对系统接口的封装,最后都要调用到execve!
二、模拟实现shell
三、内建命令——以chdir为例
相关文章:
七、进程程序替换
文章目录 一、进程程序替换(一)概念(二)为什么程序替换(三)程序替换的原理(四)如何进行程序替换1. execl2. 引入进程创建——子进程执行程序替换,会不会影响父进程呢? &…...
C++核心编程——详解运算符重载
文章目录💬 一.运算符重载基础知识①基本概念②运算符重载的规则③运算符重载形式④运算符重载建议 二.常用运算符重载①左移(<<)和右移(>>)运算符重载1️⃣重载后函数参数是什么?2️⃣重载的函数返回类型是什么?3️⃣重载为哪种…...
2023年前端面试汇总-CSS
1. CSS基础 1.1. CSS选择器及其优先级 对于选择器的优先级: 1. 标签选择器、伪元素选择器:1; 2. 类选择器、伪类选择器、属性选择器:10; 3. id 选择器:100; 4. 内联样式:1000&a…...
Java调用Pytorch实现以图搜图(附源码)
Java调用Pytorch实现以图搜图 设计技术栈: 1、ElasticSearch环境; 2、Python运行环境(如果事先没有pytorch模型时,可以用python脚本创建模型); 1、运行效果 2、创建模型(有则可以跳过…...
【EasyX】实时时钟
目录 实时时钟1. 绘制静态秒针2. 秒针的转动3. 根据实际时间转动4. 添加时针和分针5. 添加表盘刻度 实时时钟 本博客介绍利用EasyX实现一个实时钟表的小程序,同时学习时间函数的使用。 本文源码可从github获取 1. 绘制静态秒针 第一步定义钟表的中心坐标center&a…...
基于XC7Z100的PCIe采集卡(GMSL FMC采集卡)
GMSL 图像采集卡 特性 ● PCIe Gen2.0 X8 总线; ● 支持V4L2调用; ● 1路CAN接口; ● 6路/12路 GMSL1/2摄像头输入,最高可达8MP; ● 2路可定义相机同步触发输入/输出; 优势 ● 采用PCIe主卡与FMC子…...
Kibana:使用 Kibana 自带数据进行可视化(一)
在今天的练习中,我们将使用 Kibana 自带的数据来进行一些可视化的展示。希望对刚开始使用 Kibana 的用户有所帮助。 前提条件 如果你还没有安装好自己的 Elastic Stack,你可以参考如下的视频来开启 Elastic Stack 并进行下面的练习。你可以开通阿里云检…...
MySQL数据库基础 07
第七章 单行函数 1. 函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数及分类 2. 数值函数2.1 基本函数2.2 角度与弧度互换函数2.3 三角函数2.4 指数与对数2.5 进制间的转换 3. 字符串函数4. 日期和时间函数4.1 获取日期、时间 4.2 日期与时间戳的转换 4.3 获…...
JVM | JVM垃圾回收
JVM | JVM垃圾回收 1、堆空间的基本结构2、内存分配和回收原则2.1、对象优先在 Eden 区分配2.2、大对象直接进入老年代2.3、长期存活的对象将进入老年代2.4、主要进行 gc 的区域2.5、空间分配担保3、死亡对象判断方法3.1、引用计数法3.2、可达性分析算法3.3、引用类型总结3.4、…...
avive零头撸矿
Avive 是一个透明的、自下而上替代自上而下的多元网络,旨在克服当前生态系统的局限性,实现去中心化社会。 aVive:一个基于 SBT 和市场的 deSoc,它使 dapps 能够与分散的位置 oracle 和 SBT 关系进行互操作。您的主权社交网络元宇宙…...
openGauss5.0之学习环境 Docker安装
文章目录 0.前言1. 准备软硬件安装环境1.1 软硬件环境要求1.2 修改操作系统配置1.2.1 关闭操作系统防火墙 1.3 设置字符集参数1.4 设置时区和时间(可选)关闭swap交换内存1.5 关闭RemoveIPC1.6 关闭HISTORY记录 2. 容器安装2. 1支持的架构和操作系统版本2…...
数据可视化大屏人员停留系统的开发实录(默认加载条件筛选、单击加载、自动刷新加载、异步加载数据)
项目需求 录入进入房间的相关数据;从进入时间开始计时,计算滞留房间的时间;定时刷新数据,超过30分钟的人数,进行红色告警; 实现流程 为了完整地实现上述需求,我们可以按照以下步骤开发&#…...
【Linux】-关于调试器gdb的介绍和使用
作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 文章目录 前言一、Linux中的debug和release二、gdb的使用**1.进入调试****2.显示代码*…...
项目开发经验
hadoop 1.namenode中有专门的工作线程池用于处理与datanode的心跳信号 dfs.namenode.handler.count20 * log2(Clust 2.编辑日志存储路径 dfs.namenode.edits.dir 设置与镜像文件存储路径 dfs.namenode分开存放,可以达到提高并发 3.yarn参数调优,单个服…...
STM32——05-按键、时钟控制、中断复位 点亮LED灯
如何点亮一颗LED灯 编程实现点灯 常用的 GPIO HAL 库函数: void HAL_GPIO_Init ( GPIO_TypeDef * GPIOx , GPIO_InitTypeDef * GPIO_Init ); void HAL_GPIO_WritePin ( GPIO_TypeDef * GPIOx , uint16_t GPIO_Pin , GPIO_PinState PinState ); void HAL_GPIO_Togg…...
VBA下载二进制文件,文本读写
这里使用了vba如下两个对象: Microsoft.XMLHTTP:文件读写,可读写二进制,可指定编码,对于utf-8编码文本文件使用FSO的TextStream对象打开,读取到的内容可能会出现乱码,可以使用该对象打开;前期绑定添加引用…...
MongoDB结合Robo 3T 1.4.3的简单操作
MongoDB的简单操作结合Robo 3T 1.4.3工具进行查询。 常用的正则表达式 /* 29 */ 正则表达式 /\* [0-9]* \*/ "_id" : ObjectId("5f3d05cdfd2aa9a8a7"), 正则表达式 \"([^\"]*_id)\".*, 使用方法:查询结果去掉注释和不需要…...
【学习笔记】[AGC048D] Pocky Game
这是一个非平等博弈。但是只要求你判断胜负,本身也不是一道结论题,所以可以用 D P DP DP来解决。 结论:第一堆石子剩的越多,先手玩家获胜的概率越大。这直接引出了一个非常感性的结论:每次取石子时要么取一堆…...
Qgis中进行Shp和Excel属性连接实现百强县公共预算空间分析
前言 在之前的博文中,将2022的全国百强县一般公共预算收入的数据下载到了本地,博客原文地址:一种使用Java的快速将Web中表格转换成Excel的方法。对于不关注时空位置关系的一般分析,到此也就基本够用了。但是,如果站在全…...
ES6 新增的循环方法
在 ES6(ECMAScript 2015)中,新增了一些循环方法,这些方法可以帮助我们更方便地遍历数组、字符串、Set、Map 等数据结构。本文将介绍一些常用的 ES6 循环方法。 for…of 循环 for…of 循环是一种遍历可迭代对象的方法,…...
移动端事件300ms延迟解决
有移动端与PC端的项目开发,那么移动端和PC端开发上是存在差异的,比如 click 事件的300ms 延迟,即移动Web页面上的click事件响应都要慢上300ms,移动设备访问Web页面时往往需要 “双击” 或者 “捏开” 来放大页面看清页面的具体内容…...
NRF52832的DFU
开发环境: Winsodw:10 nRF5_SDK:17.1.0 1 工具安装 1.1 gcc-arm-none-eabi Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer 下载“gcc-arm-none-eabi-10.3-2021.10-win32.exe”,接提示安装。注意安装完…...
开源WebRTC库放大器模式在采集桌面图像时遇到的DPI缩放与内存泄漏问题排查
目录 1、在非100%的显示比例下放大器采集到的桌面图像不全问题 1.1、通过manifest文件禁止系统对软件进行缩放 1.2、调用SetThreadDpiAwarenessContext函数,禁止系统对目标线程中的窗口进行缩放 1.3、使用winver命令查看Windows的年月版本 2、使用放大器模式遇…...
敲黑板!java反射机制和原理
获取Class对象:首先,你需要获取表示要操作的类的Class对象。可以使用以下三种方式之一来获取Class对象: Class.forName()方法:使用类的全限定名获取Class对象,例如:Class<? Class<?> clazz MyC…...
【大数据工具】HBase 集群搭建与基本使用
HBase 集群搭建 HBase 安装包下载地址:https://archive.apache.org/dist/hbase/ 安装 HBase 的前提: ZooKeeper 集群 OKHadoop 集群 OK 1. HBase 集群安装 1. 将 HBase 软件包上传至 Hadoop0 解压并重命名 使用 FileZilla 将 hbase-1.3.1-bin.tar.g…...
【Java】数组详解
文章目录 一、数组的基本认识1.1 数组的概念1.2数组的创建与初始化1.3 数组的使用 二、数组的类型 — 引用类型2.1 JVM 内存分布2.2 什么是引用类型2.3 基本类型变量与引用类型变量的区别2.4 Java 中的 null 三、数组的应用3.1 保存数据3.2 函数参数3.3 函数返回值 一、数组的基…...
NumPy库的学习
本文主要记录的是笔者在B站自学Numpy库的学习笔记。 引入numpy库 import numpy as np矩阵的创建 创建一个二行三列的矩阵。 array np.array([[1,2,3],[2,3,4]])查看array的行数、形状、元素数量 print("number of dim:",array.ndim) print("shape:"…...
CentOS安装IRIS
最近电脑提搞了,可以无顾虑创建虚拟机了,试一下在Linux安装IRIS,适用CentOS7.6上安装Intersystem公司的IRIS数据库,资料基本是空白,分享一下。 首先安装解压软件unzip和libicu,最小化安装的缺,…...
华为OD机试真题 JavaScript 实现【最多几个直角三角形】【2023Q1 100分】
一、题目描述 有 N 条线段,长度分别为 a[1]-a[n]。 现要求你计算这 N 条线段最多可以组合成几个直角三角形,每条线段只能使用一次,每个三角形包含三条线段。 二、输入描述 第一行输入一个正整数 T (1< T< 100) ,表示有…...
vue3中的reactive、ref、toRef和toRefs
目录 reactivereactive的实现原理使用reactive的注意事项 refref的实现原理使用ref的注意事项 toRef和toRefsref和reactive的使用比较 reactive reactive用于创建响应式对象,它返回一个对象的响应式代理。即:它返回的对象以及其中嵌套的对象都会通过 Pr…...
网站服务器是网站的空间吗/推广网站排名
前言 Apollo是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端。本文介绍了配置的概念、配置中心的必要性以及Apollo的特点,着重拆解分析Apollo客户端的设计原理,…...
网站开发项目比赛/舆情信息网
目的 本身装有python3.8,和一些依赖包。同时想使用Spyder类似MATLAB工具箱的功能Variable Explorer。 环境 win10python3.8spyder5.0.5 步骤 1、Spyder安装 按照官网建议,可使用Anaconda安装。若没有,可使用Windows独立安装包ÿ…...
网站做可信认证多少钱/国家高新技术企业查询
进程原语和线程原语是啥意思本文向您展示如何将WebSphere ESB StockQuote样本(IBM Integration Designer随附)中的资源转换为IBM Integration Bus资源。 StockQuote示例使用带有SOAP / JMS Web服务绑定的导出。 由StockQuote中介流记录输入的JMS消息&…...
网站建设公司运营/app推广引流
java 对称加密算法实现详解发布时间:2020-08-24 14:26:05来源:脚本之家阅读:99作者:小破孩123前言对于信息的加密方式多种多样,之前为大家介绍了一种自己设计的加密方式,有兴趣的朋友可以欣赏一下ÿ…...
泉州手机端建站模板/惠州网站seo
今天编写一份Python基础代码,经过Linux上传到github上,遇到点问题,已经解决1.首先sudo su 进入root 用户2.ls 检查出当前文件下有什么文件3. cd 进入你将要上传的文件夹下4.git init(在本机上想要创建一个新的git仓库)5.git add -A(这里的-A是…...
上海it公司/站长工具seo优化建议
//简单邮件传输协议类 System.Net.Mail.SmtpClient client new System.Net.Mail.SmtpClient(); client.Host "smtp.163.com";//邮件服务器 client.Port 25;//smtp主机上的端口号,默认是25. client.DeliveryMetho…...