首先先使用execl函数,这个比较的简单,所以我们先看这样的代码
为什么我们执行我们的程序,最后跑起来的确实ls的命令? 所以execl的作用是让我们(进程)用exec*函数,执行起来新的程序。 会替换掉原本的程序,执行我们新调用的程序。
就是把原本的代码和数据段替换成我们后来调用的需要执行的代码和数据。 所以原本我们写的printf程序结束的标志就没有看到这样的结果。 此时的进程的替换并没有创建新的进程,只不过是直接用老的进程的页表来指向后来调用的代码和数据。 站在被替换的代码和数据角度来看:本质就是这个程序被加载到内存了。 怎么加载? 所以exec类似于一种Linux上的加载进程。 ==之前我们讲过,操作系统对于任何人来说都不会相信的,所以exec函数把一个存在磁盘外设中的代码数据能够运行起来,那就说明其中的exec*要么本身属于系统调的函数,要么就是其中的内核包括系统调用。== execl的返回值几乎可以不用关心,因为只要替换成功的话,即使能够返回的话,也没有任何的效果。反之,只要是能够继续运行了,无论execl返回的是什么,后面的程序都不再是我们之前想要的结果了。
这样能够正常输出的也就是表明了程序出现了问题。
创建子进程,目的是让子进程完成任务,之前我们创建的都只能是再父进程的基础上,但是今天我们学习的调用的函数,能够让我们的子进程执行一个和父进程毫不相关的全新程序。程序替换带来的意义! 其中数据的写时拷贝是之前的在同一个进程的运行时候会发生的事情。但是呢,像现在这个样子的时候,我们的子进程执行的代码和原来已经相差很大了,那么现在该怎么进行呢?当然也是进行写时拷贝啊! 因为我们调用execl的时候就会让代码被重新改写,这样的话为了保证父进程和子进程的相互的独立性,代码也就需要写时拷贝。
返回值不重要,不多描述
l相当于是list,就是列出所有需要执行的命令行参数。
其中第一个参数表示的含义就是我们需要执行的程序的指定的路径。关键是怎么找到 后面的参数表示的基本上就是在命令行中怎么执行,就怎么传参。 最后一定要用NULL来结尾。 之前已经有了代码的解释,就不再展示细节了
v相当于vector,相当于数组。
这样就能够成功的完成程序替换
这两个和上面不一样的只有第一个参数是不一样的,所以两个挑一个出来讲的话,就能够让两个都明白了。 带p的含义就是用户可以不传要执行的文件的路径(但是文件名要传),直接告诉exec,我要执行谁就行。在PATH路径下查找*
其中的execvpe中的最后一个e表示的是environment. 补充知识, 当我们想要多个代码同时编程可执行的程序的话,需要像下面这样做,这么做的做法参考之前的写Makefile的教程
最后一个如果传的是自定义的环境变量,那就会整体替换环境变量。请看我的gitee上的代码,如果可以可是下载下来试试看看 那如果我们只想稍微修改一下老的环境变量呢?
直接这样就行了。