Linux--进程程序替换

替换原理

1.当fork创建子进程后,父进程与子进程执行相同的代码,往往子进程要调用exec函数去执行新的程序。(让一个进程去执行一个全新的程序)
2.当进程调用exec,则当前进程的代码和数据全部被替换,堆和栈也要重新分配。
3.调用exec成功没有返回值,失败返回-1.

  • 为什么调用成功没有返回值?
    因为调用exec成功,则当前进程的代码和数据已经被替换,以前的堆和栈已经被销毁,返回值也保存在栈中,栈已经被销毁,则返回值不存在。

如下可以证明没有返回值:

#include
#include

int main()
{
    int ret = execl("./hello","./hello",NULL);
    printf("%d\n",ret);                                                                                                                            
    return 0;
}

运行结果如下:(发现没有输出ret的值,说明执行成功没有返回值)
这里写图片描述
4.调用exec并不创建新进程,所以调用exec前后,进程的pid不变。

替换函数

1.有6种以exec开头的替换函数,统称为exec函数。

#include

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);  //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
#include

int main()
{
    execl("/bin/ls","ls","-l",NULL);                                                                                                               
    return 0;
}

运行结果
Linux--进程程序替换_第1张图片
对于命令ls -l的运行结果如下:
Linux--进程程序替换_第2张图片
可以发现两个运行结果一致,只是通过终端执行的命令里面的字会带颜色(这是权限的问题)。
2.示例2:(让进程去执行./hello程序,./hello是hello.c编译生成的一个可执行程序)
hello.c

#include

int main()
{
    printf("hello world\n");                                                                                                                       
    return 0;
}

execl.c

#include
#include

int main()
{
    execl("./hello","./hello",NULL);
    return 0;                                                                                                                                      
}

运行结果:
这里写图片描述

execv

int execv(const char* path,const char* argv);

1.程序代码

#include
#include

int main()
{
    char* argv[] = {"ls","-l",NULL};                                                                                                               
    execv("/bin/ls",argv);
    return 0;
}

2.运行结果
Linux--进程程序替换_第3张图片
注意:argv数组必须以NULL作为结束,否则程序运行就会出现错误,例如下面的程序就是错误的。

#include
#include

int main()
{
    char* argv[] = {"ls","-l"};
    execv("/bin/ls/",argv);                                                                                                                        
    return 0;
}

这里写图片描述

execlp

int execlp(const char* file,const char* arg,...);

1.程序代码

#include
#include

int main()
{
    execlp("ls","ls","-l",NULL);                                                                                                                   
    return 0;
}

2.运行结果
Linux--进程程序替换_第4张图片

execvp

int execvp(const char* file,const char* argv);

1.程序代码:

#include
#include

int main()
{
    char* argv[] = {"ls","-l",NULL};
    execvp("ls",argv);                                                                                                                             
}

2.运行结果:
Linux--进程程序替换_第5张图片

execle

int execle(const char* path,const char* grg,...,char* const  envp[]);

1.程序代码
(1)hello.c(里面通过getenv函数获得AAA环境变量的内容)

#include
#include

int main()
{
    printf("AAA=%s\n",getenv("AAA"));                                                                                                              
    printf("hello world\n");
    return 0;

}

(2)execle.c(envp为自己设置的环境变量的数组,以NULL作为结束标志)

#include
#include

int 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。
Linux--进程程序替换_第6张图片

execve

int execve(const char* path,const char* argv,char* const envp[]); 

1.程序代码

#include
#include

int main()
{
    char* argv[] = {"./hello",NULL};
    char* envp[] = {"AAA=456",NULL};
    execve("./hello",argv,envp);                                                                                                                   
    return 0;
}

2.运行结果
Linux--进程程序替换_第7张图片

你可能感兴趣的:(linux,进程程序替换,execle,execv,execl)