程序替换原理:
- 1.将磁盘中的程序,加载如内存结构
- 2.重新建立页表映射,谁执行程序替换,就重新建立谁的映射(子进程)
效果:让我们的父进程和子进程彻底分离,并让子进程执行一个全新的程序
子进程原来映射到父进程,现在子进程申请自己的物理内存,让子进程指向自己的数据段,和代码段,让父子进程彻底分离,这个过程叫进程程序替换。这个过程是没有产生新的进程
execl使用操作
头文件 <unistd.h>
execl共有7种接口,但都是对象接口的封装。调用execve
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 int main() 5 { 6 printf("---------------------------------"); 7 // execl("/usr/bin/pwd","pwd",NULL); 8 9 execl("/usr/bin/ls","ls","-a","-l",NULL); 10 printf("aaa"); 11 printf("aaa"); 12 return 0; 13 }
在程序9行 进行了程序替换操作 看下实际运行效果
可以看出 实际运行效果 后面的aaa并没有打印 为什么?
因为:执行了execl,程序就替换了,execl后面的代码也被替换了,早就不存在的。
替换成功了,程序就跑到了你写的路径下,比如此程序就到了ls的程序下,结束时,也是通过ls结束的。
而替换失败时,就会执行后面的代码
也就说明 成功不返回,失败返回-1
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 5 int main() 6 { 8 pid_t id=fork(); 9 if(id==0) 10 { 20 execl("/usr/bin/ls","ls","-a","-l",NULL); 27 exit(1); 28 } 29 int statas=0; E> 30 int ret=waitpid(id,&statas,0); 31 if(ret==id) 32 printf("父进程等待成功!\n"); 33 34 return 0; 35 }
这段程序生成父子进程
让子进程去到新的进程去,父进程能否执行下面的代码?
可以发现,是可以执行下面的代码的?
为什么?
子进程替换不会影响父进程,因为进程具有独立性。
当进程替时,代码和数据都发生了写实拷贝完成父子的分离
execv
execv和execl的区别 只有传参方式不同
#include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 5 int main() 6 { 7 extern char**environ; 8 pid_t id=fork(); 9 if(id==0) 10 { 11 char *const argv_[]= 12 { 13 (char*)"ls", 14 (char*)"-a", 15 (char*)"-l", 16 NULL 17 }; 18 19 execv("/usr/bin/ls",argv_); 27 exit(1); 28 } 29 int statas=0; E> 30 int ret=waitpid(id,&statas,0); 31 if(ret==id) 32 printf("父进程等待成功!\n"); 33 34 return 0; 35 }
execv传数组 execl传列表
execlp("ls","ls","-a","-l",NULL);
execlp也是一样的效果,只不过execlp要传的指针在PATH中时 可以不用写绝对路径
execl可以完成一种语言对另一种语言的调用
只不过这两种语言需要线允许起来即可
因为makefile的普通命名只能单次生成单个程序
利用all可以同时完成多个程序
.PHONY:all 2 all:execpp exec
all后依赖的是能执行的程序 既完成编译过后的可执行文件的名称
随后我们再实现一个cpp文件
#include<iostream> 2 #include<stdlib.h> 3 using namespace std; 4 5 int main() 6 { 11 cout<<"C++"<<endl; 12 cout<<"C++"<<endl; 13 cout<<"C++"<<endl; 14 cout<<"C++"<<endl; 15 cout<<"C++"<<endl; 16 cout<<"C++"<<endl; 17 cout<<"C++"<<endl; 18 return 0; 19 }
22 execl("./execpp","execpp",NULL); 23 //execl("/home/moxuan/m10d5/execpp","execpp",NULL);
在原来exec.c的文件内用execl实现对cpp文件的调用(两条代码选其中一条均可,效果一样)
随后生成这两个可执行文件。
只执行exec.c
可以发现,两个文件都运行了,就实现了一种语言对另一种语言的调用 这里是c语言调用c++
添加环境
在从cpp内实现此条代码
cout<<"MYPATH : "<<getenv("MYPATH")<<endl;
在c中 实现此条代码
char *const env_[]={ (char*)"MYPATH=you can see me!",NULL}; execle("./execpp","execpp","env");
运行效果
发现MYPATH后并未打印 因为添加环境变量是覆盖式
另一种方法
extern char**environ; execle("./execpp","execpp",NULL,environ);
在外设置环境变量
随后执行两种文件
可以发现不会有打印不出的结果,而是两种环境遍历均打印
标签:execl,NULL,程序,execpp,ls,进程,include,替换 From: https://www.cnblogs.com/LonelyMoNan/p/16756529.html