目录
进程替换,是指用一个新进程来替换此时正执行的进程。新进程从头开始执行自己的代码。
进程替换时,新进程依旧沿用原进程的PCB结构体、mm_struct结构体和页表。但是页表改为映射新进程的物理内存。因此实际上,进程替换并没有创建新的进程。
同时EIP寄存器内记录新进程的代码地址,新进程从头开始执行。
当进程替换成功后,原进程已经消失,所以新进程执行完毕后,并不会继续执行原进程。
操作系统为我们提供了非常多的函数接口用于进程替换。
这些接口统统包含于
可以使用man指令来查询这些接口信息。
man 3 execl
①const char *path
这个参数是用来确定新进程可执行程序的路径。
参数输入应为:程序完整/相对路径+程序名
可以按如下方式使用:
- //伪代码
- execl("./proj", ...);//相对路径
- execl("/home/me/927/proj", ...);//绝对路径
②const char *arg, ...
这一组参数其实都是命令行参数。
此处的arg输入程序名即可,其实就是命令行参数中的argv[0]。
而 ... 所代表的可变参数列表就表示如果有需要也可以继续输入其他命令行参数,但一定要以NULL来结尾。
使用如下:
- 1 #include
- 2 #include
- 3 #include
- 6 int main()
- 7 {
- 8 pid_t id = fork();
- 9 if(id == 0) {
- //让子进程改为ls -al指令
- 10 execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
- 11 }
- 12 else{
- 13 printf("I am father\n");
- 14 }
- 15 return 0;
- 16
- 17 }
这个接口与execl所不同的就是它的命令行参数是用指针数组传的。
从名字就可以判断出来,execv中v即vector。而execl之流需要传的是类似于链表那样一个个的输入,因此execl采用了可变参数列表,execl中l即list。
定义原文如下:
红色大意就是:这些函数提供了以空字符串为结尾的指针数组来替代链表。
因此,argv指针数组最后一个空间应是空指针,又因为argv所代表的是整个命令行参数,所以argv的第一个参数是变量名,即argv[0] = 程序名。
在使用时,第一个参数path与execl一致,传程序路径。第二个参数传指针数组即可。
以上述代码为例,只需要将arg和...替换成数组。
- #include
- #include
- #include
- char* argv[] = {
- "ls",
- "-a",
- "-l",
- NULL
- };
- int main()
- {
- pid_t id = fork();
- if(id == 0) {
- //让子进程改为ls -al指令
- execv("/usr/bin/ls", argv);
- }
- else{
- printf("I am father\n");
- }
- return 0;
- }
结果同execl。
这两个参数与execl、execv最大不同是程序路径,命令行参数与之前两个一致(看函数名也会清楚的)。
但程序路径只需要给出程序名即可。
原文如下:
小编来翻译一下红线大意:
这个可执行程序会在PATH环境变量中去寻找,如果没有找到,会默认从当前路径中寻找。
因此,当我们想调的程序是系统命令或就在本路径下时,可以直接输入程序名。但是不同路径下就需要按照绝对/相对路径输入(这样那我为啥不直接使用execl呢doge)。
使用方式与前者们大差不差:
- //伪代码
- int main()
- {
- pid_t id = fork();
- if(id == 0) {
- //让子进程改为ls -al指令
- execlp("ls", "ls", "-a", "-l", NULL);
- //第一个ls是路径,后面是命令行参数
- }
- else ...
- }
这两个函数允许自定义程序环境变量。
与之前execl、execv相同,环境变量传链式结构或指针数组。
filename传入文件绝对/相对路径+文件名。
*envp[]传入带有环境变量的指针数组。当然最后应以NULL结尾。
当创建失败时,函数会返回-1并在errno中记录该错误原因。
errno是一个系统参数,由操作系统直接维护,会记录最新的错误。
除此之外,execl、execv、execlp、execvp、execle都是在第三手册中,只有execve在第二手册中。
man execve //查看execve使用手册
这是因为execve是真正的系统调用接口,其他的都是进一步的封装,其底层调用execve接口。
好的软件的作用是让复杂的东西看起来简单——Grady Booch
如有错误,敬请斧正