一般情况下,对应的语言写的程序只能调用对应的语言的接口,而不能调用其他语言的接口,如C++不能调用Java或者Python或者Shell等语言的接口,那么如果我们想要调用别人写的程序应该怎么办呢?那么进程程序替换就能够很好地帮助我们解决这个问题,这在很大程度上减少了我们编程的成本,学会进程程序替换,在很多时候,如果有现成的程序,那么我们不需要自己再去写一个,是不是方便很多了?
所谓进程程序替换,顾名思义,就是使用一个新的程序替换原有的程序,进程将执行新程序的代码,而不再执行原有程序的代码,前面我们已经学习了如何创建一个进程,一般情况下,进程程序替换都不会使用父进程直接进行进程程序替换,而是让父进程调用fork()函数创建一个子进程,让子进程去执行一个新的程序即可

- 进程程序替换的原理:
假如刚开始父子进程都是执行程序a.exe,后面,想要让子进程执行b.exe了,那么此时就要进行进程程序替换,替换的过程就是首先将b.exe从磁盘加载进内存,然后重新建立子进程的页表,更新子进程的页表中的映射关系,注意,这里修改的是页表中的物理地址而不是虚拟地址,此时父子进程代码块中虚拟地址是一样的,但是通过页表映射出来的物理地址是不一样的,从而实现父子进程的代码彻底分离,此时父子进程的代码是互不干扰的,很好地满足了进程的独立性

在学习进程程序替换之前,我们知道当一个父进程创建一个子进程之后,父子进程的代码是共享的,子进程只能执行父进程的代码块,但是现在我们的需求增加了,我们不仅要让子进程能够执行父进程的代码块,也要能够让子进程能够做一些父进程不能做的事情,也就是能够执行一个全新的代码(程序),这样就能实现父子进程做的事情有所差异,大大提高了办事效率,同时也使父子进程的代码彻底分离,维护进程的独立性
在学习使用进程程序替换的相关接口之前我们首先需要明确一点,这个在使用接口的时候需要做什么事情,很明显,最基本的我们首先得知道这个程序在哪里,其次,我们还需要知道怎么执行这个程序,在我们前面学习一些指令的时候,有些指令是可以携带选项的有些指令可以不用携带选项。总结起来就是我们需要知道要执行的程序的路径和怎么执行新程序




替换成新程序的代码




















实验结果

注意:

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



这里需要注意:需要将PATH所在行的代码进行注释,因为execle传入环境变量的方式是覆盖式的,所以当向该程序传入自定义环境变量之后,原来的环境变量就不存在了,那么不存在的话,通过getenv()去获取的话结果就会出现空指针,那么再对空指针进行打印就会出现段错误
makefile文件

实验结果

其中上面第一种通过environ来获取环境变量的方式其实我们也可以不采用程序替换的方式进行获取,按照普通的一个程序也可以获取到自定义变量,因为只需要通过export将该自定义环境变量导出为系统的环境变量即可,其实本质上是一样的,下面给出演示
源代码:


实验结果:

今天我们主要介绍了进程程序替换及其基本原理,还有介绍了很多程序替换有关的函数接口