linux--进程程序替换

目录

一、什么是进程程序替换

二、原理:

三、为什么要进行程序替换

四、六种替换函数

 命名理解

(1)函数execl

(2)函数execv

 (3)execlp

 (4)execvp

 (5)execle

(6)execve


一、什么是进程程序替换

所谓进程程序替换,顾名思义,就是使用一个新的程序替换原有的程序,进程将执行新程序的代码,而不再执行原有程序的代码,前面我们已经学习了如何创建一个进程,一般情况下,进程程序替换都不会使用父进程直接进行进程程序替换,而是让父进程调用fork()函数创建一个子进程,让子进程去执行一个新的程序即可。

二、原理:

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

   从上图当中我们可以知道一个进程的出现必须先在PCB结构当中先构建自己的PCB块,有了对应的虚拟地址之后,然后虚拟地址通过页表映射的方式在物理地址当中找到位置,然后将磁盘当中的程序加载进入对应的物理地址。

三、为什么要进行程序替换

当一个父进程在创建子进程之后,父子进程的代码是共享的,子进程只能执行父进程的代码块,但是现在我们不仅要让子进程能够执行父进程的代码块,同时也要能够让子进程能够做一些父进程不能做的事情,也就是能够执行一个全新的代码(程序),这样就能实现父子进程做的事情有所差异,大大提高了办事效率,同时也使父子进程的代码彻底分离,维护进程的独立性。

目的:让子进程帮我们执行特定的任务。

四、六种替换函数

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

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

我们也可以在x-shell中通过 man 命令来查看。

如上的函数:

如果调用成功,则加载新的·程序,从启动代码开始执行,不在返回。

如果调用出错,返回-1

所以exec函数只有出错的返回值,而没有成功的返回值

  •  命名理解

        每一个函数看似十分复杂,其实,每一个不同的字母都各代表一个含义:

l (list)表示参数采用列表
v(vector)参数采用数组
p (path)有p自动搜索环境变量
e (env)表示自己维护环境变量

  •  各函数之间的关系

        

 事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve。

(1)函数execl

#include <unistd.h>

int execl(const char* path, const char* arg, ...);

返回值:失败返回-1

参数1:待替换程序的路径,比如“/usr/bin/ls” 

参数2:待替换程序的名称,比如“ls”

后面的参数:待替换程序的选项,如 -a -l等,最后一个参数为 NULL,表示选项传递结束

注意: 参数选项传递结束或不传递参数,都要在最后加上 NULL,类似于字符串的 '\0'

案例:(这里替换调用的是 ls 命令)

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main(){
  4   printf("程序替换:\n");                                                   
  5   int ret=execl("/usr/bin/ls","ls",NULL);
  6 
  7   //可以通过返回值查看是否返回成功
  8   if(ret==-1)
  9   {
 10     printf("替换失败\n");
 11   }
 12 
 13   return 0;
 14 }

运行结果:

(2)函数execv

"v"代表的是"vector" 即execv是以vector的方式传递参数的。

#include <unistd.h>

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

返回值:失败返回-1

参数1:待替换程序的路径,比如:"/usr/bin/ls"

参数2:待替换程序名及其命名构成--数组

注意:参数的最后仍需要加上NULL

 #include<stdio.h>
 #include<unistd.h>
     
     int main(){
       printf("程序替换:\n");
       char* const argv[]={"ls","-a",NULL};   //以数组传入                                 
       int ret=execv("/usr/bin/ls",argv);
     
       //可以通过返回值查看是否返回成功
      if(ret==-1)
      {
        printf("替换失败\n");
      }
    
      return 0;
    }

 (3)execlp

#include <unistd.h>

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

返回值:失败返回-1

参数1:待替换程序名,比如“ls”,"pwd","clear"

参数2--N:可变参数列表,命令选项

该函数进行程序替换时,不需要写path路径,因为P代表有自动搜索的功能

#include<stdio.h>
#include<unistd.h>

int main(){
  printf("程序替换:\n");
  int ret=execlp("ls","ls","-l",NULL);

  //可以通过返回值查看是否返回成功
  if(ret==-1)
  {
    printf("替换失败\n");
  }

  return 0;
}

 (4)execvp

#include <unistd.h>

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

返回值:失败返回 -1

参数1:待替换程序名,需要位于 PATH 中

参数2:待替换程序名及其命名构成的数组

注意:如果file的路径不在PATH中,则会替换错误

#include<stdio.h>
#include<unistd.h>

int main(){
  printf("程序替换:\n");
  char* const argv[]={"ls","-a","-l",NULL};
  int ret=execvp("ls",argv);

  //可以通过返回值查看是否返回成功
  if(ret==-1)
  {
    printf("替换失败\n");
  }

  return 0;
}

 (5)execle

#include <unistd.h>

int execl(const char* path, const char* arg, ..., char* const envp[]);
 

e表示env环境变量表,可以将自定义或当前程序·中的环境和变量传给替换程序

第一个参数:待替换程序的路径,比如:"/bin/ls"

第二个参数:待替换程序名及其命名构成--数组

...

最后一个参数:替换成功后,待替换程序的环境变量表,可以自定义

#include <iostream>
#include <unistd.h>

int main(int arg, char **args)
{
  execle("/bin/ls","ls","-l", NULL);
  
  return 0;
}

(6)execve

execve 是系统真正提供的程序替换函数,其他替换函数都是在调用 execve

比如:

execl 相当于将链式信息转化为 argv 表,供 execve 参数2使用
execlp 相当于在 PATH 中找到目标路径信息后,传给 execve 参数1使用
execle 的 envp 最终也是传给 execve 中的参数3

#include <unistd.h>

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

返回值:替换失败返回 -1

参数1:待替换程序的路径

参数2:待替换程序名及其参数组成的argv表

参数3:传递给待替换程序的环境变量表

#include <iostream>
#include <unistd.h>

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值