【linux】进程替换

进程替换可是个好东西,可以帮助我们模拟小shell~,

先看代码&&现象:

在这里插入图片描述
在这里插入图片描述
这就是程序替换,将原本的程序代替,然后去执行新的程序

所以我们发现我们原程序后半段的printf就没有打印了,因为后半段已经被替换掉了。

原理:

先输出一个结论:exec系列的函数并没有创建新的进程。

我们的进程 = 内核数据结构 + 代码和数据
在这里插入图片描述
本质exec*系列的函数就是类似linux下的一个加载函数,将磁盘上的文件加载到物理内存中。

将代码改为多进程:

可是如果我们还是想继续执行没被执行到的代码怎么办?

答案是使用fork(),创建子进程,让子进程被替换,父进程执行刚刚未被执行的代码。

在这里插入图片描述
记住不要忘记回收子进程哦,在这里插入图片描述
由此可以看到fork创建出来的子进程有两个用途

  1. 执行部分父进程代码
  2. 执行一份全新的代码

我们exec就是后者。

我们的进程之间是具有独立性的,即具有独立的内核数据结构和代码与数据,数据会按需发生写时拷贝。
我们在以前的理解中代码是具有只读属性的,但是在OS眼中一视同仁,为了执行一份全新的程序,代码也会发生写时拷贝。
在这里插入图片描述

使用所有的替换方法,认识参数的含义:

在这里插入图片描述

我们再来回顾一下execl函数
我们一直说exec是execute(执行的英文)的缩写,而后边的l代表

  • l(list) : 表示参数采用列表

同理,我们后边如果跟v p e的字母的函数就是如下含义:

  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量

接下来我们来使用一下这些函数。

execv

在这里插入图片描述

execvp:

在这里插入图片描述

execlp:

在这里插入图片描述

execvpe:

重量级函数登场。
看到这个e我们肯定可以想到环境变量,而v我们已经知道这与命令行参数其实是一样的,
这是不是与我们main函数的参数有些过分巧合了呢?
没错,这些变量就是传递给我们将要执行新的程序的参数。

在这个函数使用讲解之前,我们先来考虑一下,我们exec系列函数可以替换我们自己的程序码?
答案是可以的,只要是进程我们几乎都可以替换(替换之前先考虑一下当前进程真的可以替换吗)。
那我们先写一个Cpp代码试验一下
在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述
这里我们也验证了一下进程没有改变的问题,替换后的进程pid是不变的,证明没有创建新的进程。

同理,Python与脚本语言也可以被C语言替换,因为他们运行起来都是进程。

接下来我们可以看execvpe这个函数了,我们已经知道这里的argv与env参数是可以被新程序的main函数接受的。

那么我们来验证一下:

在这里插入图片描述
在这里插入图片描述
实验结果:
在这里插入图片描述
于是我们就知道execvpe可以自定义的传入环境变量。

  1. 可以采用全新的环境变量给子进程
  2. 可以用旧的环境变量给子进程
  3. 可以在旧的环境变量基础上改变一点给子进程。

我们看一下第三点如何实现:
在这里插入图片描述
extern + putenv即可实现。

系统调用:execve:

在这里插入图片描述
我们的所有exec系列C函数都是根据这个系统调用进行封装的。
为的是应对不同情况下的调用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值