进程替换..

1、单进程版 – 最简单的先看看程序替换
在这里插入图片描述
在这里插入图片描述
现象就是
1、我们用自己的进程封装了内置指令ls,并且代码中execl 后 printf 的after并没有打印出来。

2、谈进程替换的原理

单进程替换基本原理
在这里插入图片描述

上面例子中execl的做法非常简单粗暴,要调用ls,那么就把mycommand这个进程的代码和数据进行替换,物理空间根据ls的大小进行调整,左边进程地址空间和页表做出相应的调整,然后从新加载的程序main函数入口处重新执行,而并没有创建新的进程!
在这里插入图片描述

3、多进程版 – 验证各种程序替换接口
在这里插入图片描述
在这里插入图片描述
子进程execl调用了ls,父进程也等待成功了,并且没有创建新进程
问题1、在子进程中执行execl会不会影响到父进程呢?如果不会的话为什么?
答:不会,写时拷贝技术,并且进程互相具有独立性

问题2.、在单继承原理说了,替换是简单粗暴的把可执行程序在物理内存中代码和数据
直接替换,那么fork之后创建的子进程把数据进行写时拷贝了,那么代码呢?它也有写时拷贝吗?
在这里插入图片描述
答案:是的,操作系统去写入这个代码,他发现这个代码是父子共享的,所以不能直接替换,所以代码也要进行写时拷贝。
所以写时拷贝不一定只在数据层面,代码上也体现。

问题3、程序替换有没有创建新的子进程?
没有,可以看到调用execl前后的子进程活着和死了之后都是同一个进程Pid

在这里插入图片描述
不创建新进程,只进行进程的程序代码和数据的替换工作!
如果是父子场景发生写时拷贝,不是父子直接替换(单进程场景)
适当的改改页表映射关系,进而让pcb执行新程序。

补充小知识:
1、现象:程序替换成功之后,exec后续的代码不会被执行,替换失败呢?才可能执行后续代码exec函数,只有失败返回值,没有成功返回值!! 替换成功后也没有地方返回

2、我们的CPU如何得知程序的入口地址?
这个入口还不是main函数而是类似CRTmain

在这里插入图片描述
Linux中形成的可执行程序,是有格式的,可执行程序不是杂乱无章的把二进制往里一放,有ELF,可执行程序的表头,可执行程序的入口地址就在表中!! !
所以刚开始一定要把表头先加载到内存当中。

验证接口

先看看execl和execlp的接口如何使用
在这里插入图片描述
execv

在这里插入图片描述

ls是一个可执行程序,它有main函数,它的命令行参数是从myargv[]传入的,即便是list也是要转换为argv[]字符串指针数组传入给ls的 main函数

linux中所有的进程都一定是别人的子进程
命令行中所有的进程都是bash的子进程
所有的进程在启动的时候都是采用exec系列函数启动执行的
exce* 函数承担的是加载器的效果!
目前要知道 我们是可以把命令行参数传递给可执行程序的
就像bash中输入命令ls 我是要启动ls这个进程?

问题:如果我们的exec能够执行系统命令,能不能执行我们自己的命令呢?? ?
答:
bash和python3 是解释器 底层都是C/C++ ,用于解释脚本Or py语言
这些语言运行起来,本质都是进程,被操作系统调度
exec
是加载器,你要运行就要使用
在这里插入图片描述
验证mycommand给自己写的程序传入的命令行参数和环境变量
在这里插入图片描述
问题:替换程序是否会替换环境变量信息?
创建子进程时,子进程就已经继承了父进程的环境变量数据,在地址空间栈区之上
那么子进程即使不传main函数的env形参 也能拿到环境变量
但是进程替换时并不会替换环境变量信息。所以程序替换你可以替换代码和数据但环境变量不会替换
运行结果看到确实没有替换环境变量
在这里插入图片描述
问题又来了
所以我如果想给子进程传递环境变量,该怎么传递???
1、新增环境变量
第一种,在bash中export设置一个新的环境变量,那么子进程替换的时候就可以拿到新增的环境变量
第二种,父进程的地址空间中直接putenv!
要想与bash的环境变量无关,就想让父进程导一个环境变量再传递给子进程,就利用putenv , putenv添加一个环境变量到调用进程的上下文,也就是谁调用就给谁导
在这里插入图片描述


与bash无关

第三种,我非得传递环境变量,那么就利用第三方变量environ,用前需声明,可以不在main写形参env
在这里插入图片描述

2、彻底替换 - 自定义环境变量
在这里插入图片描述

4、总结
exec*函数的关系
左边六个库函数的区别:只是传参的不同 最终都转化为execve系统调用
在这里插入图片描述

5、自定义shell(媒婆)

bash(王婆) 为了不砸自己招牌,创建了子进程,这样子进程崩了就不会影响Bash
bash如何创建子进程呢?
答:fork()

我们上面写的代码不就是fork创建子进程,只不过命令是在代码中硬编码写好的-a -b -c,如果我把命令行参数以命令行形式传进入,动态的让他去执行命令,那它不就是一个shell了吗
在这里插入图片描述

问题:我们shell本身的环境变量是从哪里来的???
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值