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

天津企业网站制作/周口网站制作

天津企业网站制作,周口网站制作,wordpress 织梦转换,金融公司网站建设文章目录 替换原理站在进程的角度站在程序的角度初体验及理解原理 替换函数函数解释命名理解exec系列函数与main函数之间的关系在一个程序中调用我们自己写的程序 替换原理 创建子进程的目的是什么? ->想让子进程执行父进程代码的一部分 执行父进程对应的磁盘代码…

文章目录

  • 替换原理
    • 站在进程的角度
    • 站在程序的角度
    • 初体验及理解原理
  • 替换函数
    • 函数解释
    • 命名理解
    • exec系列函数与main函数之间的关系
    • 在一个程序中调用我们自己写的程序

替换原理

创建子进程的目的是什么?
->想让子进程执行父进程代码的一部分

执行父进程对应的磁盘代码中的一部分

->想让子进程执行一个全新的程序

让子进程想办法加载磁盘上指定的程序,执行新程序的代码和数据->进程的程序替换

![[进程控制 2023-01-30 15.38.00.excalidraw|700]]

站在进程的角度

没有创建新的进程(PCB尤其是pid是没有变化的),只是程序的替换

站在程序的角度

  1. 这个程序被加载到内存中了->称exec函数为"加载器"
  2. 既然我自己的代码能加载到新的程序,操作系统也是
    1. 先创造进程数据结构(PCB),在再需要的时候加载代码和数据

初体验及理解原理

int execl(const char *path, const char *arg, ...);
将指定的程序加载到内存中,让制定进程进行执行

需要解决两个问题:1.找到程序 2.如何执行(cmd 选项一 选项二)
后面的三个点:可变参数列表:可以给函数不同数量的参数,例如:printf\scanf

示范程序:

#include<stdio.h>
#include<unistd.h>int main()
{//.c->exe->load->process->运行->执行我们现在所写的程序printf("process is running...\n");//load->exeexecl("/usr/bin/ls"/*要执行哪一个程序*/, "ls", "-a","-l",NULL/*你想怎么执行*/);//所有的exel程序都必须以NULL结尾,证明你把参数传完了//但是此时就不能打印出下面的句子
//因为他也是代码,是在execl的,execl执行完毕的时候,代码已经被完全覆盖,开始执行新的程序的代码了,所以printf就无法执行了!
//但是如果调用失败了,就是没有替换成功,就会打印出来下面的句子printf("process running done...\n");
}

由上述的例子我们可以看出这个函数的特点:
只有失败才会返回-1(只需要做错误处理,即:只要返回值,就一定是调用错误了)
perror("execl");可以打印错误原因.
调用成功时则不返回,因为此时已经替换了,后续的代码已经没有意义了,没有必要返回值了.(成功了就和接下来的代码无关了)

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

由虚拟地址空间+页表来保证进程的独立性,一旦有执行流想替换代码或者数据,就发生写时拷贝.->说明写时拷贝在代码区也可以发生的!

但是我们一般不直接在父进程进行程序替换,而是创建新的子进程进行程序替换.
于是我们优化上面的代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
##include<sys/types.h>
#include<sys/wait.h>
int main()
{printf("process is running...\n");pid_t id = fork();assert(id != -1);if (id == 0){//这里的替换会影响父进程吗?//不会。进程具有独立性,在执行exec时会发生写时拷贝//类比:命令行怎么写,这里就怎么传参sleep(1);execl("/usr/bin/ls", "ls", "-a", "-l", "--color=auto", NULL);exit(-1);//must failed}int status = 0;pid_t ret = waitpid(id,&status,0);if (ret > 0){printf("wait success: \nexit code: %d,sig: %d\n",(status>>8)&0xFF,status&0x7F);}}

替换函数

其实有六种以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 execve(const char *path, char *const argv[], char *const envp[]);

其中,execve是系统调用,其余的都是封装,是为了让我们有更多的选择性

函数解释

这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
如果调用出错则返回-1
所以exec函数只有出错的返回值而没有成功的返回值
不用对该函数进行返回值判断,只要继续向后运行一定是失败的

命名理解

这些函数原型看起来很容易混,但只要掌握了规律就很好记。
l(list) : 表示参数采用列表
v(vector) : 参数用数组

可以将所有的执行参数放入数组中,统一传递,而不用进行使用可变参数方案.

char* const argv_[] = {"-ls","-a","-l","--color=auto",NULL
};
execv("usr/bin/ls",argv_);

p(path) : 有p自动搜索环境变量PATH

带p字符的函数,不用告诉我程序的路径,你只要告诉我程序的名字,我会自动在环境变量PATH中进行可执行程序的查找.
execlp("ls", "ls", "-a", "-l", "--color=auto", NULL);
这里前面的ls是告诉系统我要执行谁,第二个是告诉系统我想要怎么执行

e(env) : 表示自己维护环境变量

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
##include<sys/types.h>
#include<sys/wait.h>
int main()
{printf("process is running...\n");pid_t id = fork();assert(id != -1);if (id == 0){sleep(1);char* const envp_[] = {(char*)"MYENV=1122233334444",NULL;}extern char** environ;//声明系统默认的环境变量列表execle("./mybin","mybin",NULL,environ);//这里是只传了系统默认的环境变量putenv((char*)"MYENV=444333222111");//将指定环境变量导入系统中environ指向对应的环境变量表中execle("./mybin","mybin",NULL,envp_);//这里是只传了你自定义的环境变量execle("./mybin","mybin",NULL,environ);//实际上,默认环境变量你不传,子进程也能获取. 这里是传了默认的环境变量加上你自己添加的环境变量exit(1);}int status = 0;pid_t ret = waitpid(id,&status,0);if (ret > 0){printf("wait success: \nexit code: %d,sig: %d\n",(status>>8)&0xFF,status&0x7F);}}

exec系列函数与main函数之间的关系

exec*系列函数的意义是:
将我们的程序加载到内存中

int main(int argc,char* argv[],char* env[])

所以应该是先加载到内存中,之后才是调用main函数,main函数中的argc argc[]分别是exec函数中的前面的两个参数,env[]是从exec函数的环境变量参数中加载出来的

![[Pasted image 20221115142525.png]]

exec调用举例如下:

#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的,需要自己组装环境变量//没有带e的话会默认传入系统默认的环境变量execve("/bin/ps", argv, envp);exit(0);
}

在一个程序中调用我们自己写的程序

首先,我们需要在makefile文件中同时创建两个文件并且同时删除两个文件,那该怎么书写呢?

.PHONY:all
all: mybin myexecmybin:mybin.cgcc -o $@ $^ -std=c99
myexec:myexec.cgcc -o $@ $^ -std=c99	.PHONY:clean
clean:rm -f myexec mybin

myexec.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
##include<sys/types.h>
#include<sys/wait.h>
int main()
{printf("process is running...\n");pid_t id = fork();assert(id != -1);if (id == 0){execl("./mybin", "mybin", NULL);exit(-1);}int status = 0;pid_t ret = waitpid(id,&status,0);if (ret > 0){printf("wait success: \nexit code: %d,sig: %d\n",(status>>8)&0xFF,status&0x7F);}}

可以使用程序替换调用任何后端语言所对应的可执行!!!


事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。
下图exec函数族 一个完整的例子:
![[Pasted image 20221115142624.png]]

相关文章:

【Linux】进程程序替换

文章目录 替换原理站在进程的角度站在程序的角度初体验及理解原理 替换函数函数解释命名理解exec系列函数与main函数之间的关系在一个程序中调用我们自己写的程序 替换原理 创建子进程的目的是什么&#xff1f; ->想让子进程执行父进程代码的一部分 执行父进程对应的磁盘代码…...

项目构建工具maven的基本配置+idea 中配置 maven

&#x1f451; 博主简介&#xff1a;知名开发工程师 &#x1f463; 出没地点&#xff1a;北京 &#x1f48a; 2023年目标&#xff1a;成为一个大佬 ——————————————————————————————————————————— 版权声明&#xff1a;本文为原创文…...

【解密ChatGPT】:从过去到未来,揭示其发展与变革

&#x1f38a;专栏【ChatGPT】 &#x1f33a;每日一句&#xff1a;天行健,君子以自强不息,地势坤,君子以厚德载物 ⭐欢迎并且感谢大家指出我的问题 文章目录 一、ChatGPT的发展历程 二、ChatGPT的技术原理 三、ChatGPT的应用场景 四、ChatGPT的未来趋势 五、总结 引言:随着…...

系统架构设计】计算机公共基础知识: 5 数学与经济管理

一 运筹方法 1 线性规划 线性规划问题的数学模型通常由线性目标函数、线性约束条件、变量非负条件组成,特点如下: (1)线性规划的可行解域是由一组线性约束条件形成的。 (2)如果存在两个最优解,则连接这两点的线段内所有的点都是最优解,而线段两端延长线上可能会超出…...

Visual Studio 2019光标变成灰色方块问题

文章目录 Visual Studio 2019光标变成灰色方块问题问题描述解决方案 Visual Studio 2019光标变成灰色方块问题 问题描述 单击和双击都无法选中单词&#xff0c;总是选择整行或者是当前光标处的前几个字符一起选中&#xff0c;没有规则&#xff0c;貌似选择单词复制&#xff0…...

C++ http协议POST body raw 字段向服务器发送请求

环境&#xff1a;ubuntu系统c使用http协议不是很方便&#xff0c;通过curl库我们可以很方便使用http协议&#xff0c;由于我的请求方式比较特殊&#xff0c;在网上没有找到相关的资料&#xff0c;之前使用python实现过一版&#xff0c;但是当设备数量超过100台时&#xff0c;程…...

通过migrate命令实现两个redis实例之间的数据迁移

本文适用于将源服务器的redis实例的key的数据迁移到其他服务器的redis实例 一、migrate简介&#xff1a; migrate用于在Redis实例间进行数据迁移&#xff0c;实际上migrate命令是将dump、restore、del三个命令进行组合&#xff0c;从而简化了操作流程。migrate命令具有原子性&…...

Unity 判断两个UI是否相交

今天碰到要判断两个UI是否相交的交互。 尝试了下&#xff0c;发现有两个方法都成功了。 1、使用Collider2D组件 分别创建两个Image组件&#xff0c;并且添加Collider2D组件&#xff0c;其中一个还要添加Rigidbody2D组件&#xff0c;如下图&#xff1a; 然后创建个判断脚本“…...

swoole process 消息通信

swoole文档&#xff1a;Swoole 文档 process子进程和父进程之间通信&#xff0c;依靠监听。子进程和父进程分别做监听。父进程写入信息&#xff0c;子进程监听接收。子进程向父进程写入&#xff0c;调用父进程监听。 子进程向父进程写入信息有两种方式&#xff0c;一种调用wr…...

uniapp跳转方式

UniApp 是一个基于 Vue.js 的跨平台开发框架&#xff0c;可以同时构建 iOS、Android、H5 和小程序等多个平台的应用。在 UniApp 中&#xff0c;我们可以使用以下几种方式进行页面之间的跳转&#xff1a; 使用 uni.navigateTo 方法&#xff1a;该方法可以在当前页面打开新的页面…...

六大排序算法:插入、选择、冒泡、快排、希尔、归并

1、插入排序 解析&#xff1a;第一个元素设定为已经排好序&#xff0c;依次选择后续的元素插入到已经排好序的组内进行排序。 图示&#xff1a; 代码&#xff1a; public static void insertionSort(int[] arr) {int n arr.length;for (int i 1; i < n; i) {int key a…...

短信登录实现(黑马点评为例)

文章目录 前言一、隐藏用户敏感信息二、短信验证登录、注册1.流程2.代码3.使用redis优化解决代码 二、登录拦截&#xff08;校验&#xff09;1.流程2.代码 总结 前言 短信登录核心知识 首先黑马点评这个短信登录是一伪验证&#xff0c;即后台调用工具类随机生成六位数字。 1.R…...

【uniapp】签名组件,兼容vue2vue3

网上找了个源码改吧改吧&#xff0c;清除了没用的功能和兼容性&#xff0c;基于uniapp开发的 样子 vue2 使用方法&#xff0c;具体的可以根据业务自行修改 <signature ref"signature" width"100%" height"410rpx"></signature>confi…...

初步利用Ansible实现批量服务器自动化管理

1.Ansible介绍 Ansible是一款开源的自动化运维工具, 在2012年由Michael DeHaan创建, 现在由Red Hat维护。Ansible是基于Python开发的,采用YAML语言编写自动化脚本playbook, 可以在Linux、Unix等系统上运行, 通过SSH协议管理节点, 无需在被管理节点安装agent。Ansible以其简单、…...

网络安全和隐私保护技术

一、定义 网络安全和隐私保护技术是指在互联网和其他网络环境中&#xff0c;通过技术手段保护网络系统、网络数据和用户隐私免于受到恶意攻击、非法访问、窃取或滥用。网络安全和隐私保护技术是保护网络安全和用户隐私的重要手段&#xff0c;是保障互联网和其他网络环境正常运…...

保险行业采购管理痛点及解决方案(数智化采购系统)

随着社会发展&#xff0c;个人和企业有了更多的金融保险需求。对于金融保险公司而言&#xff0c;需要在采购合规的基础上&#xff0c;基于数智化能力&#xff0c;让经营变得更加高效和智能。 1、围绕重点领域&#xff0c;业务加速布局。 保险行业结合自身业务经营重点&#x…...

光学仿真 | 仿真推动以人类视觉感知为本的汽车显示设计

如果产品设计无法使终端用户产生共鸣&#xff0c;就不会存在卓越的工程设计。您可以设计一种结构坚固的方向盘&#xff0c;但如果它被放在错误的位置&#xff0c;就无法实现其用于转向的主要目的。 同样&#xff0c;在围绕人类视觉进行设计时&#xff0c;显示器其实无需具备尽…...

判断两个对象是否不相等operator.ne()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断两个对象是否不相等 operator.ne() 选择题 下列代码执行输出的结果是? import operator print("【执行】operator.ne(8,8)") print(operator.ne(8,8)) print("【执行】…...

2023年云计算发展趋势:生活的智能未来

目录 引言1 智能家居的崭新时代2 无人驾驶的崭新时代3 虚拟现实的扩展与改进4 人工智能的综合应用5 云计算的可持续性结语 引言 时光荏苒&#xff0c;科技的飞速发展已经成为当今社会的标志之一。在这个数字化时代&#xff0c;云计算已经成为推动技术革新和生活方式改变的关键…...

Spring Boot项目中通过 Jasypt 对属性文件中的账号密码进行加密

下面是在Spring Boot项目中对属性文件中的账号密码进行加密的完整步骤&#xff0c;以MySQL的用户名为root&#xff0c;密码为123321为例&#xff1a; 步骤1&#xff1a;引入Jasypt依赖 在项目的pom.xml文件中&#xff0c;添加Jasypt依赖&#xff1a; <dependency><…...

2.3 矩阵消元

一、消元矩阵 消元矩阵执行消元步骤用到的矩阵。从第 i i i 个方程减去 l i j l_{ij} lij​ 乘第 j j j 个方程&#xff08;将 x j x_j xj​ 从第 i i i 行中消去&#xff09;。我们需要很多个简单的矩阵 E i j E_{ij} Eij​&#xff0c;每一个对应一个主对角线下方要消…...

Docker 从构建开始导出一个镜像

docker build docker build命令用于从Dockerfile创建一个镜像。它的基本格式如下&#xff1a; docker build [OPTIONS] PATH | URL | -这里的PATH是Dockerfile所在的路径&#xff0c;URL是一个Git仓库地址&#xff0c;-表示从标准输入读取Dockerfile。 docker build命令的一…...

案例研究|腾讯音乐娱乐集团与JumpServer共探安全运维审计解决方案

近年来&#xff0c;得益于人民消费水平的提升以及版权意识的加强&#xff0c;用户付费意愿和在线用户数量持续增长&#xff0c;中国在线音乐市场呈现出稳定增长的发展态势。随着腾讯音乐于2018年12月上市&#xff0c;进一步推动了中国在线音乐市场的发展。 腾讯音乐娱乐集团&a…...

如何卸载在linux下通过rpm安装的mysql

目录 1.先关闭MySQL服务并查看运行状态 2.使用 rpm 管道命令的方式查看已安装的mysql 3. 使用rpm -ev 命令移除安装 4. 删除MySQL数据库内容 1.先关闭MySQL服务并查看运行状态 如果之前安装过并已经启动&#xff0c;则需要卸载前请先关闭MySQL服务 systemctl stop mysqld…...

docker复制镜像文件

一、复制镜像 #1. 查找本机已有的镜像docker images |grep xxxx#2. 将镜像复制出来指向到xxxx.tar的文件中 docker save 343cca04e31d > xxxx.tareg: 二、加载镜像 直接将拷贝好的镜像包直接加载即可 docker load < myimage.tar...

自动驾驶学习笔记(六)——Apollo安装

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 Apollo安装 硬件配置 安装Ubuntu…...

四阶龙格库塔与元胞自动机

龙格库塔法参考&#xff1a; 【精选】四阶龙格库塔算法及matlab代码_四阶龙格库塔法matlab_漫道长歌行的博客-CSDN博客 龙格库塔算法 Runge Kutta Method及其Matlab代码_龙格库塔法matlab_Lzh_023016的博客-CSDN博客 元胞自动机参考&#xff1a; 元胞自动机&#xff1a;森林…...

Mac安装opencvJava踩坑

SpringBoot导入opencv依赖 先将jar包添加到libraries中在resources目录下创建lib文件夹并复制jar包到这里添加如下依赖&#xff0c;并刷新maven <dependency><groupId>org.opencv</groupId><artifactId>opencv</artifactId><version>4.8.0…...

YOLOv8-Pose推理详解及部署实现

目录 前言一、YOLOv8-Pose推理(Python)1. YOLOv8-Pose预测2. YOLOv8-Pose预处理3. YOLOv8-Pose后处理4. YOLOv8-Pose推理 二、YOLOv8-Pose推理(C)1. ONNX导出2. YOLOv8-Pose预处理3. YOLOv8-Pose后处理4. YOLOv8-Pose推理 三、YOLOv8-Pose部署1. 源码下载2. 环境配置2.1 配置CM…...

django+drf+vue 简单系统搭建 (1) - django创建项目

本系列文章为了记录自己第一个系统生成过程&#xff0c;主要使用django,drf,vue。本人非专业人士&#xff0c;此文只为记录学习&#xff0c;若有部分描述不够准确的地方&#xff0c;烦请指正。 建立这个系统的原因是因为&#xff0c;在生活中&#xff0c;很多觉得可以一两行代码…...