详解:进程程序替换

news/2024/10/17 15:28:05/

目录

    • 一、前言
    • 二、什么是进程程序替换?
    • 三、进程程序替换的原理
    • 四、为什么要进行进程程序替换?
    • 五、如何进行进程程序替换?(常见进程程序替换系统调用接口)
    • 六、利用所学综合知识实现一个shell
    • 总结

一、前言

一般情况下,对应的语言写的程序只能调用对应的语言的接口,而不能调用其他语言的接口,如C++不能调用Java或者Python或者Shell等语言的接口,那么如果我们想要调用别人写的程序应该怎么办呢?那么进程程序替换就能够很好地帮助我们解决这个问题,这在很大程度上减少了我们编程的成本,学会进程程序替换,在很多时候,如果有现成的程序,那么我们不需要自己再去写一个,是不是方便很多了?

二、什么是进程程序替换?

所谓进程程序替换,顾名思义,就是使用一个新的程序替换原有的程序,进程将执行新程序的代码,而不再执行原有程序的代码,前面我们已经学习了如何创建一个进程,一般情况下,进程程序替换都不会使用父进程直接进行进程程序替换,而是让父进程调用fork()函数创建一个子进程,让子进程去执行一个新的程序即可

三、进程程序替换的原理

  • 进程替换前的效果图
    当一个进程成功创建一个子进程之后,父子进程的情况如下图所示:
    在这里插入图片描述
    这个时候,我们这里先针对代码和数据进行分析,其他内容暂不做考虑,此时父子进程都没有修改代码和数据,因此,父子进程的代码和数据都是指向同一块内容的,也就是代码和数据共享的,如果其中一方对数据进行修改,则这一方就会进行写时拷贝,如果想要执行不同的代码,则此时就要进行进程程序替换
  • 进程程序替换的原理
    假如刚开始父子进程都是执行程序a.exe,后面,想要让子进程执行b.exe了,那么此时就要进行进程程序替换,替换的过程就是首先将b.exe从磁盘加载进内存,然后重新建立子进程的页表更新子进程的页表中的映射关系,注意,这里修改的是页表中的物理地址而不是虚拟地址,此时父子进程代码块中虚拟地址是一样的,但是通过页表映射出来的物理地址是不一样的,从而实现父子进程的代码彻底分离,此时父子进程的代码是互不干扰的,很好地满足了进程的独立性
  • 进程替换之后的效果图
    在这里插入图片描述

四、为什么要进行进程程序替换?

在学习进程程序替换之前,我们知道当一个父进程创建一个子进程之后,父子进程的代码是共享的,子进程只能执行父进程的代码块,但是现在我们的需求增加了,我们不仅要让子进程能够执行父进程的代码块,也要能够让子进程能够做一些父进程不能做的事情,也就是能够执行一个全新的代码(程序),这样就能实现父子进程做的事情有所差异,大大提高了办事效率,同时也使父子进程的代码彻底分离,维护进程的独立性

五、如何进行进程程序替换?(常见进程程序替换系统调用接口)

在学习使用进程程序替换的相关接口之前我们首先需要明确一点,这个在使用接口的时候需要做什么事情,很明显,最基本的我们首先得知道这个程序在哪里,其次,我们还需要知道怎么执行这个程序,在我们前面学习一些指令的时候,有些指令是可以携带选项的有些指令可以不用携带选项。总结起来就是我们需要知道要执行的程序的路径和怎么执行新程序

  1. execl
  • 查看execl的使用方法
    在这里插入图片描述
  • execl的使用
  • 源代码
    在这里插入图片描述
  • makefile文件
    在这里插入图片描述
  • 实验结果
    在这里插入图片描述
    上面的实验是没有子进程的,是一个纯单进程的实验,下面将演示一个多进程的例子执行ls指令,而且我们会发现一个现象,我们明明在源代码中写了两条printf函数语句,但是结果只有一条打印出来,原因是,当我们进行程序替换之后,子进程将不再执行原来的父进程的代码块,由进程程序替换的结果我们可以知道,子进程中的代码内容完全被替换成新程序的代码
  • execl多进程实验
    源代码
    在这里插入图片描述
    makefile文件
    在这里插入图片描述
    实验结果
    在这里插入图片描述
    实验分析
    上面的实验思路就是父进程创建一个子进程,然后本来子进程是要执行父进程的代码块和父进程进行代码共享的,但是我们在子进程中调用execl函数接口,因此,在子进程中会进行程序替换
  1. execv函数接口的使用
  • 查看手册
    在这里插入图片描述
    这个函数和上面介绍的execl是类似的,都需要做两件事,第一知道新程序的路径,第二知道怎么执行新程序(是否携带选项进行执行),但是这个函数和上面介绍的函数的区别就是这个函数的第二个参数是一个字符指针数组,上面哪个函数是一个一级字符指针,其实区别就在于,上面那个函数传参传的是字符串列表,这个函数传参传的是字符指针数组
    实验演示:
  • 源代码
    在这里插入图片描述
  • makefile文件
    在这里插入图片描述
  • 实验结果
    在这里插入图片描述
    需要注意的是
  • execv函数中使用的是字符指针数组,而不是传字符串列表
  • 数组中的字符串是常量字符串,也就是const char类型的,而这个字符指针数组中存放的又是char的,是支持修改的,因此这里需要将const char强转为char类型
    在这里插入图片描述
  1. execlp函数接口的使用
  • 查看手册
    在这里插入图片描述
  • execlp的使用(实验演示)
    源代码
    在这里插入图片描述
    makefile文件
    在这里插入图片描述
    实验结果
    在这里插入图片描述
    execlp中的p指的是环境变量中的PATH,指的是系统直接到环境变量PATH中去寻找对应程序,因此在传第一个参数的时候不需要带路径
    注意:
    在这里插入图片描述
    这个参数列表中有两个"ls",我们需要知道的是这两个ls的含义是不一样的,是不能省略的,第一个是告诉系统要执行哪个程序,好让系统知道去找谁,第二个是在函数的第二个参数之中的,也就是为了告诉系统怎么执行这个程序
  1. execvp的使用
  • 查看手册
    在这里插入图片描述
  • 实验演示使用方法
    源代码
    在这里插入图片描述
    makefile文件
    在这里插入图片描述
    实验结果
    在这里插入图片描述
  1. execle函数接口的使用
  • 查看手册
    在这里插入图片描述
  1. execle的使用
    源代码
    在这里插入图片描述
    makefile文件(形成多可执行程序)
    在这里插入图片描述
    导出自己的环境变量
    在这里插入图片描述

实验结果
在这里插入图片描述
注意:
在这里插入图片描述

上面的实验中,我们使用函数execle传入第三方变量environ,environ的作用是获取系统中的环境变量,上面这个代码的意思就是将这个变量environ传给test程序,那么如果想要在该程序中打印出自定义的环境变量,则需要将自定义环境变量加入系统环境变量,test程序才能获取,如果没有加入系统环境变量,则getenv()函数获取不到对应的环境变量则会返回空指针,那么就会导致printf函数打印空指针从而造成程序崩溃

六、利用所学综合知识实现一个shell

敬请期待

总结


http://www.ppmy.cn/news/812.html

相关文章

安装GCC教程

安装GCC-9.3.0全指导 一.安装准备 1_1下载GCC-9.3.0安装包* 手动下载辅助包,自动下载太慢,咱直接自己动手解决 ps:下载源精选国内清华源,速度无敌 wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar…

切换模糊化的自适应滑模控制

目录 前言 1.系统描述 2.控制器设计 3.模糊逼近切换项 4.仿真分析 4.1仿真系统 4.2仿真模型 4.3仿真结果 4.4结论 5.总结 前言 前面两篇文章分别介绍了切换增益模糊化和系统不确定项f或g模糊化,其原理都是使用模糊控制对未知量进行估计,上两篇…

阿里云Redis性能压力测试(二十)

文章目录1.云Redis性能压力测试2.安装redis-banchmark压测工具3.压测两节点的Redis集群4.压测四节点的Redis集群4.1.扩容集群为四节点4.2.压力测试5.压测结果对比1.云Redis性能压力测试 我们当前Redis集群是2个节点2个分片,使用redis-benchmark工具对Redis集群进行…

Numpy入门[3]——Numpy数组及其索引

Numpy入门[3]——Numpy数组及其索引 参考: https://ailearning.apachecn.org/ 使用Jupyter进行练习 先导入numpy: import numpy as np产生数组 从列表产生数组 mylist [0, 1, 2, 3] a np.array(mylist) aarray([0, 1, 2, 3])或者直接将列表传入 a …

springboot简述

文章目录一、SpringBoot简介1、springboot快速入门1、开发步骤1.创建springboot入门项目2.创建controller3.启动服务器4.测试2、对比spring3、springboot工程快速启动4.切换web服务器二、配置文件1.配置文件格式2.properties配置文件3.yaml格式配置文件1.语法规则2.yaml配置文件…

【python与数据分析】实验十三 北京市空气质量

目录 一、实验内容 二、完成情况 三、数据分析 1.问题描述 2.编程思路 3.程序代码 4.程序运行结果 (1)2014年-2019年AQI时间序列折线图 (2)各年AQI折线图、AQI直方图、PM2.5与AQI散点图、空气质量整体情况的饼图 ​&am…

HTML+CSS大作业:众志成城 抗击疫情 抗击疫情网页制作作业 疫情防控网页设计

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

import一个“太极”库,让Python代码提速100倍

众所周知,Python的简单和易读性是靠牺牲性能为代价的—— 尤其是在计算密集的情况下,比如多重for循环。 不过现在,大佬胡渊鸣说了: 只需import 一个叫做“Taichi”的库,就可以把代码速度提升100倍! 不信&…