目录
一、进程替换的基本概念
根据我们之前所学,我们可以知道我们所创建的所有的子进程,执行的代码,都是父进程代码的一部分。如果我们想让子进程去执行新的程序呢??-----执行全新的代码和访问全新的数据,不在和父进程有瓜葛------ 而这一过程就可以理解为程序替换。
那么接下来,本节内容将围绕各种实现进程替换的接口进行讲解。
二、exec系列函数
当我们想要进行程序替换时,就需要使用到该系列函数,那么接下来,让我们看看,该系列函数都有些什么吧。
这里一共有六个函数,看起来好像很麻烦的样子,实际上只要你理解其中的含义,就很容易了。
2.1 execl系列函数
根据上面的图,我们来对execl的待传参数进行解析。
execl() --- ... 叫做可变参数列表
对于其第一个参数(const char* path)表示我们要替换的程序的程序文件路径+文件名(要执行,就得先找到)
第二个参数(解决如何执行的问题)程序名+参数
样例 execl("/usr/bin/ls","ls","-a","-l",NULL) --- 需要以NULL结尾
那么接下来,我们写一段具体的代码来试一试吧。
看一下运行结果:
很明显,我们完成了我们想要完成的指令的内容,但是我们后面的printf却并没有输出任何东西,这里说明:
exec*这样的函数,如果当前进程执行成功,则后续代码没有机会在执行了,因为被替换掉了。(一旦失败,则会执行后续)
exec*只有失败的返回值,没有成功的返回值。
我们再来看看其他execl系列的函数:
execlp --- 我们现在大概理解了 execl 代表的时什么意思,那这个后面的p是什么意思呢?
不难发现,我们刚刚在传参的时候,传入了具体的路径,/usr/bin/ls ,而p则代表的系统会帮我们导入当前环境的环境变量PATH,这样就能简化我们的传参内容。
继续写一段代码来试试:
很明显,执行结果也是没有问题的,这里可能有人会问,为什么我所传入的参数有两个 “ls” ,这第一个 ls 代表是要进行程序替换的指定文件名(路径虽然有了,但是你也需要告诉系统是去哪个文件中执行哪个命令吧),那么第二个就是要执行的命令咯。
来到我们的第三个函数 --- execle
这个e带表的是什么呢? --- 其其实代表的是环境变量,也就是说可以传入一个自己的环境变量。关于这里,大家可以自行尝试尝试。
2.2 execv系列函数
相较于 execl(我们可以将 l 理解为 list)--- execv 中的v 代表的是一个数组,其内容其实就是存的我们 list 所传的东西,写段代码给大家看看就能理解了。
那么剩下的相信大家通过对execl的学习,是可以自己掌握的了,这里我就不过多的赘述了。
2.3 替换原理
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。