进程程序替换
原理:用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
如图所示:
进程程序替换的应用: 实现一个简易的 shell( mini_shell )
https://blog.csdn.net/TheWindRisesll/article/details/86182766
替换函数
- 有6种以 exec 开头的替换函数,统称为 exec函数:
int execl(const char* path,const char* arg,...); //最后以NULL结束
int execlp(const char* file,const char* arg,...);
int execle(const char* path,const char* grg,...,char* const envp[ ]);
int execv(const char* path,const char* argv,..., char *const envp[ ] );
//argv数组也以NULL结束;char *const envp[ ] —>环境变量
int execvp(const char* file,const char* argv);
事实上,只有 execve 是系统调用,其它函数都调用了 execve ,以上5个函数都是对 execva 的封装
int execve(const char* path,const char* argv,char* const envp[]);
//envp数组也是NULL结束
PATH环境变量 会在默认路径中查找
注意:进程程序替换,不创建新的子进程,替换的是代码段,
一旦替换成功,后面的所有程序不会再运行,并且无返回值。
失败时(给一个不存在的路径),才会有返回值
详情请见下图:在 excel 语句前后各打印一句指令
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
printf("hello!\n");
execl("/bin/ls","ls","-a","-l","NULL");
//第一个参数"/bin/ls"是要执行哪一个,后面的"ls"及后面的选项表示在命令行上想怎么执行
printf("hello word!\n");
}
结果如下:只会打出 excel 前的语句 “hello”
- 函数参数
path : 表示对应的文件在哪个目录下(查找可执行程序);
file : 只用填文件名,系统会在PATH下找;
envp[]:表示自己设置的,替换后的程序的环境变量 - 命令理解
l(list):表示参数采用列表形式
v(vector):参数采用数组形式
p(path):有p自动搜索环境变量PATH
e(envp):表示自己设置(维护)环境变量(自己设置的环境变量是什么,则最新程序的环境变量就是什么)