专门做10s视频的网站,哈尔滨网络科技公司网站,域名邮箱登录入口,企业网站设计wordpress进程程序替换 替换概念替换函数execl()execv()execvp()/execlp()execle()/execvpe() 如何在C/C程序里面执行别的语言写的程序。小tips 替换概念
当进程调用一种exec函数时#xff0c;该进程的用户空间代码和数据完全被新程序替换#xff0c;从新程序的代码部分开始运行。调用… 进程程序替换 替换概念替换函数execl()execv()execvp()/execlp()execle()/execvpe() 如何在C/C程序里面执行别的语言写的程序。小tips 替换概念
当进程调用一种exec函数时该进程的用户空间代码和数据完全被新程序替换从新程序的代码部分开始运行。调用exec并不创建新的进程所以调用exec前后该进程的id并未改变。
大概意思就是程序替换只是把程序换了仅仅是从1号程序换到了2号程序修改了页表的映射地址但是并没有创建新的PCB因此没有创建新的进程。 这就是进程替换的概念
替换函数
在linux手册里有6个相似的函数他们虽然参数列表不一样但是功能一样。
如果这些函数调用成功则加载新的程序从启动代码开始执行不再返回。如果出错则返回-1。所以exec函数只有出错的返回值而没有成功的返回值。
execl()
l列表的形式传入参数 int extcl(const char * path, const char* argv,…); 参数 path是要打开可执行程序的路径 argv,… 这个语法表示可变的参数列表可以传入多个不定个数的参数最后一个参数传入NULL表示参数传递完成。 描述不清楚看个例子就明白了 1 #includestdio.h2 #includeunistd.h5 int main()6 {7 printf(当前进程开始\n);8 //execl(/usr/bin/ls,ls,--colorauto,-l,NULL);9 //一旦调用成功后续代码都不会执行了 10 execl(/usr/bin/ls,ls,--colorauto,-l, -i,NULL);11 //execl(/usr/bin/top, top, NULL);12 printf(当前进程结束\n); 13 return 0; 14 } 因为Linux系统下一切皆文件ls命令其实就是一个可执行程序我们使用execl函数执行这个程序。我们可以改变可变参数列表来使用ls命令不同的功能。
execv()
v数组的形式传入参数 int extcv(const char * path, char *const argv[]); 参数 path仍然是文件路径。 char *argv[]指针数组以数组的形式传入。 为了更加适应实际的应用场景我们使用父进程fork子进程然后使用子进程进行进程替换这样不会影响父进程的执行。 如下
7 #define NUM 328 int main()9 {10 pid_t id fork();11 12 if(id 0)13 {14 //子进程15 // ls -a -l16 printf(子进程开始执行pid %d \n,getpid());17 //传入指针数组18 char *const _argv[NUM] {19 (char*)ls,20 (char*)-l,21 (char*)-i,22 NULL23 };24 execv(/usr/bin/ls,_argv); //传入指针数组25 exit(1);26 }27 else{28 //父进程29 printf(父进程开始等待pid %d \n, getpid()); 30 int status 0;31 pid_t ret waitpid(-1, status, 0); //阻塞等待32 if(ret0)33 {34 printf(等待成功,退出码为%d \n, WEXITSTATUS(status));35 }36 }37 return 0;38 } 可以看到子进程帮助父进程完成了执行ls命令并且没有影响父进程的执行。
execvp()/execlp()
p表明第一个参数不再是文件路径而是通过环境变量就可以找到的程序。 看下面的例子更能清楚的解释
execvp()的例子 7 #define NUM 328 int main()9 {10 pid_t id fork();11 12 if(id 0)13 {14 //子进程15 // ls -a -l16 printf(子进程开始执行pid %d \n,getpid());17 //传入指针数组18 char *const _argv[NUM] {19 (char*)ls, 20 (char*)-l, 21 (char*)-i, 22 NULL 23 }; 24 //execv(/usr/bin/ls,_argv); 25 execvp(ls,_argv); //因为环境变量的存在我们可以只输入ls便可找到该文件。 26 exit(1); 27 } 28 else{ 29 //父进程 30 printf(父进程开始等待pid %d \n, getpid()); 31 int status 0; 32 pid_t ret waitpid(-1, status, 0); //阻塞等待 33 if(ret0) 34 { 35 printf(等待成功,退出码为%d \n, WEXITSTATUS(status)); 36 } 37 } 38 return 0;39 } execlp()例子 仅仅将上面的代码25行换成26行的内容即可 25 //execvp(ls,_argv); //因为环境变量的存在我们可以只输入ls便可找到该文件。 26 execlp(ls, ls, -l, -i, NULL); execle()/execvpe()
e可以维护自己的环境变量将环境变量传给要替换的进程。
以execle为例 将上面的子进程调用部分修改 7 #define NUM 328 int main()9 {10 11 //设置一个环境变量为的是 让子进程拿到12 //因为环境变量具有全局属性13 char *const _env[NUM]{14 (char*)xty123456789,15 NULL16 };31 execle(./myexe, mycmd, -a, NULL, _env); //修改成这样//其中列表参数是随便传的myexe是调用的可执行程序。myexe:1 #includestdio.h2 #includestdlib.h3 4 int main()5 {6 7 printf(得到的环境变量xty:%s\n, getenv(xty));8 return 0;9 }可知myexe获取到了环境变量。
如何在C/C程序里面执行别的语言写的程序。 //使用这个命令即可运行
python test.py首先写一个python文件脚本。待会我们就是用c程序执行它。 使用execlp()调用比较合适。 1 #include stdio.h2 #includestdlib.h3 #includeunistd.h4 #includesys/types.h5 #includesys/wait.h6 int main()7 {8 pid_t id fork();9 if(id 0)10 {11 //子进程,调用别的语言写的程序12 execlp(python, python, test.py, NULL);13 exit(-1);14 }15 else{16 //父进程17 int status 0;18 printf(父进程开始等待: \n);19 int ret waitpid(-1, status, 0); //阻塞等待20 if(ret 0)21 {22 printf(父进程等待成功子进程退出码为%d \n,WEXITSTATUS(status));23 24 }25 } 26 return 0;27 }我们可以看出python脚本被我们成功调用
小tips
我们在运行py脚本时需要运行python这个程序。因为python是一个解释器我们需要使用解释器来解释test.py文件。
python test.py如果我们给该test.py文件加上执行x权限那么我们这样即可运行该文件 因此将上面的execlp调用参数修改为下面这样也可以 //12 execlp(python, python, test.py, NULL);12 execlp(./test.py, test.py, NULL);上面就是程序替换的相关知识更深入的内容还请读者自行查阅和学习。