朋友们好,这里简单介绍一下LINUX学习中关于进程控制部分的一个小板块----进程替换做出一些学习上的总结,实属初学,若文章中有理解不当的地方还望指出,谢谢大家!
文章目录
一:什么是进程程序替换
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支)子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
也就是说,如果我们想要创建出来的子进程创建全新的程序,那么这时就要用到程序替换!
二:程序替换的原理
- 将磁盘中的程序加载入内存结构。
- 重新建立页表映射,谁执行程序替换,就重新建立谁的映射。
💡💡💡:让父进程和子进程彻底分离,并让子进程执行一个全新的程序!
三:如何进行程序替换
这里我们查看Linux的man手册可知,针对系统调用接口**execve()**提供了6种不同场景下的封装:
我们想要执行一个全新的程序思考两件事:
1. 程序在哪?
2. 怎么执行?
3.1:execl(…)
int execl(const char path, const char arg, …)**
第一个参数代表程序路径,第二个参数代表程序名字,后面表示可变参数,注意最后以NULL结尾!
示例:
结果:
我们也可以替换为自己写的程序!!!例如
我们先编写一个mycmd.cpp程序并编译成可执行程序mycmd:
然后程序替换:
效果示例:
3.2:execv(…)
execv与execl相比除了传参方式的不同,其他均一样!
v可看作vector,代表以数组的方式传参!
调用示例:
3.3:execlp(…)
相比于execl多了一个p,有p(path)表示自动去环境变量PATH中搜索。
调用示例:
结果:
我们注意到调用的地方有两个 ”ls“,第一个代表取环境变量PATH包含的路径中取搜索,第二个”ls“表示替换新进程的程序名。
3.4:execvp(…)
同样的相比于execlp,v表示以数组传参!
调用示例:
结果:
3.5:execle(…)
相比于前面几个替换函数,这个函数多了一项传环境变量的功能!
int execl(const char* path, const char* arg, …, char* const envp[ ])
mycmd.cpp文件如下:
结果:
当程序替换后,由于这种方式是覆盖式传递环境变量,因此导致PATH环境变量没有了,所以打印不出PATH环境变量!
此时我们选择另一种方式传递环境变量:
extern char environ**
由下图运行结果展示,此时PATH环境变量没有被覆盖,MYPATH环境变量没有!那么此时就需要导入环境变量了!
然后再重新编译运行:
3.6:总结
1. l(list):表示采用列表传参。
2. v(vector):表示用数组传参。
3. p(path):表示自动搜索环境变量path。
4. e(env):表示自己维护环境变量。