替换原理
1.当fork创建子进程后,父进程与子进程执行相同的代码,往往子进程要调用exec函数去执行新的程序。(让一个进程去执行一个全新的程序)
2.当进程调用exec,则当前进程的代码和数据全部被替换,堆和栈也要重新分配。
3.调用exec成功没有返回值,失败返回-1.
- 为什么调用成功没有返回值?
因为调用exec成功,则当前进程的代码和数据已经被替换,以前的堆和栈已经被销毁,返回值也保存在栈中,栈已经被销毁,则返回值不存在。
#include
#includeint main()
{
int ret = execl("./hello","./hello",NULL);
printf("%d\n",ret);
return 0;
}
运行结果如下:(发现没有输出ret的值,说明执行成功没有返回值)
文章图片
4.调用exec并不创建新进程,所以调用exec前后,进程的pid不变。
替换函数
1.有6种以exec开头的替换函数,统称为exec函数。
#includeint 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* constenvp[]);
int execv(const char* path,const char* argv);
//argv数组也要以NULL结束
int execvp(const char* file,const char* argv);
int execve(const char* path,const char* argv,char* const envp[]);
//envp数组也是NULL结束//事实上,只有execve是系统调用,其它函数都调用了execve
2.函数参数
path:表示对应的文件在哪个目录下(也表示我要执行的程序是哪一个);
file:只用填文件名,系统会在PATH下找;
envp[]:表示自己设置的,替换后的程序的环境变量
3.命令理解
l(list):表示参数采用列表形式
v(vector):参数采用数组形式
p(path):有p自动搜索环境变量PATH
e(envp):表示自己设置(维护)环境变量(自己设置的环境变量是什么,则最新程序的环境变量就是什么)
execl
int execl(const char* path,const char* arg,...);
1.示例1:(让进程去执行ls -l命令)
#include
#includeint main()
{
execl("/bin/ls","ls","-l",NULL);
return 0;
}
运行结果
文章图片
对于命令ls -l的运行结果如下:
文章图片
可以发现两个运行结果一致,只是通过终端执行的命令里面的字会带颜色(这是权限的问题)。
2.示例2:(让进程去执行./hello程序,./hello是hello.c编译生成的一个可执行程序)
hello.c
#includeint main()
{
printf("hello world\n");
return 0;
}
execl.c
#include
#includeint main()
{
execl("./hello","./hello",NULL);
return 0;
}
运行结果:
文章图片
execv
int execv(const char* path,const char* argv);
1.程序代码
#include
#includeint main()
{
char* argv[] = {"ls","-l",NULL};
execv("/bin/ls",argv);
return 0;
}
2.运行结果
文章图片
注意:argv数组必须以NULL作为结束,否则程序运行就会出现错误,例如下面的程序就是错误的。
#include
#includeint main()
{
char* argv[] = {"ls","-l"};
execv("/bin/ls/",argv);
return 0;
}
文章图片
execlp
int execlp(const char* file,const char* arg,...);
1.程序代码
#include
#includeint main()
{
execlp("ls","ls","-l",NULL);
return 0;
}
2.运行结果
文章图片
execvp
int execvp(const char* file,const char* argv);
1.程序代码:
#include
#includeint main()
{
char* argv[] = {"ls","-l",NULL};
execvp("ls",argv);
}
2.运行结果:
文章图片
execle
int execle(const char* path,const char* grg,...,char* constenvp[]);
1.程序代码
(1)hello.c(里面通过getenv函数获得AAA环境变量的内容)
#include
#includeint main()
{
printf("AAA=%s\n",getenv("AAA"));
printf("hello world\n");
return 0;
}
(2)execle.c(envp为自己设置的环境变量的数组,以NULL作为结束标志)
#include
#includeint main()
{
char* envp[] = {"AAA=123",NULL};
execle("./hello","./hello",NULL,envp);
return 0;
}
2.运行结果
当执行execle.c程序之前,运行hello.c程序,发现AAA的环境变量为NULL,因为不存在。
文章图片
执行execle.c,发现hello.c程序里面的环境变量AAA值变成了自己设置的123。
文章图片
execve
int execve(const char* path,const char* argv,char* const envp[]);
1.程序代码
#include
#includeint main()
{
char* argv[] = {"./hello",NULL};
char* envp[] = {"AAA=456",NULL};
execve("./hello",argv,envp);
return 0;
}
【linux|Linux--进程程序替换】2.运行结果
文章图片
推荐阅读
- linux|Linux操作系统-进程控制
- 【LINUX】进程创建-进程等待-进程替换-进程终止
- Linux|Linux之进程创建/进程终止/进程等待/程序替换
- 学习工具|关于嵌入式容器技术的调研
- Centos|Linux机器密码正确,但无法登陆
- Linux下安装JDK
- ubuntu|opencv图像基本操作
- 网络|万字长文详解Istio
- 服务器|【SOC】经典输出hello world