Linux进程程序替换

目录

一、引入

二、程序替换的原理

三、替换函数

(一)execl

(二)execv

(三)execle

四、环境变量


一、引入

  • 我们所创建的所有子进程,执行的代码,都是父进程的一部分。如果想让子进程执行新的程序呢?执行全新的代码和访问全新的数据不再和父进程有关系-------那么就需要进程替换

二、程序替换的原理

程序替换(也称为程序加载或程序执行)是指将一个程序从磁盘(或其他存储介质)中读取到内存中,然后用它来替换当前正在运行的进程的代码和数据。 

Linux进程程序替换_第1张图片

三、替换函数

  • 其实有六种以exec开头的函数,统称exec函数
man excel //命令查看
#include `
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[]);
  • 这些函数如果调用成功加载新的程序从启动代码开始执行,不再返回。
  • 如果调用出错则返回-1
  • 所以exec函数只有出错的返回值而没有成功的返回值
  • l(list) : 表示参数采用列表
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量
man execl
man execve

Linux进程程序替换_第2张图片 

(一)execl

int execl(const char *path, const char *arg, ...);
  • path表示要执行的程序是谁,在哪?,程序本质也是一个文件(需要先找到程序的路径+文件名)
  • arg表示如何执行的问题?命令行怎么写,就将参数怎么传
  • ...表示可变参数列表
  #include    
  #include//execl的头文件    
  int main()    
  {    
      pid_t id = fork();    
      if(id == 0)    
      {    
          printf("pid: %d, exec command begin\n",getpid());    
          sleep(2);    
          execl("/usr/bin/ls","ls","-a","-l","-n",NULL); //最后必须以NULL结尾  
          printf("pid: %d, exec command end\n",getpid());    
      }    
      else{    
          //父进程    
          pid_t rid = waitpid(-1, NULL, 0);    
          if(rid > 0)    
          {    
              printf("wait success, rid: %d\n", rid);    
          }    
          else if(rid == 0)    
          {    
              printf("child is alive, wait again, father do other thing....\n");    
          }                                                                                                                        
          else{    
              printf("wait failed!\n");    
          }    
      }    
      return 0;    
  } 

Linux进程程序替换_第3张图片

(二)execv

int execv(const char *path, char *const argv[]);
  • v(vector):表示以数组的形式传参
  • 第二个参数表示以指针数组的形式传参
  #include    
  #include//exec的头文件    
  #include//exit的头文件    
  int main()    
  {    
      pid_t id =fork();    
      if(id == 0)    
      {    
          //子进程    
          char *const argv[]={"ls","-a","-l",NULL};    
          printf("pid: %d, exec command begin\n",getpid());    
          execv("/usr/bin/ls",argv);                                                                                                                        
          printf("pid: %d, exec command end\n",getpid());    
          exit(1);    
      }    
      
          return 0;    
      }

Linux进程程序替换_第4张图片

(三)execle

int execle(const char *path, const char *arg, ...,char *const envp[]);
  • envp 参数是一个指向字符串数组的指针,表示新程序的环境变量。这个数组以NULL结尾
  • process.c文件 
  #include    
  #include//exec的头文件    
  #include//exit的头文件    
  #include    
  int main()    
  {    
      char* const myenv[]={    
        "MYVAL1=111111",    
        "MYVAL2=222222",    
        "MYVAL3=333333",    
          NULL    
      };    
      pid_t id =fork();    
      if(id == 0)    
      {    
          //子进程    
          printf("pid: %d, exec command begin\n",getpid());    
          execle("./test","test","-a","-b",NULL,myenv);    
          printf("pid: %d, exec command end\n",getpid());    
          exit(1);    
      }    
          return 0;    
  }
  •  test.cc文件
  #include    
  using namespace std;    
  int main(int argc, char *argv[],char *env[])    
  {    
      cout<
  • makefile文件
.PHONY:all    
all:test process    
    
test:test.cc    
    g++ -o $@ $^ -std=c++11    
process:process.c    
    gcc -o $@ $^ -std=c99    
    
.PHONY:clean    
clean:    
    rm -f process test

Linux进程程序替换_第5张图片

 

四、环境变量

  • 当我们进行程序替换的时候,子进程对应的环境变量,是可以直接从父进程来的
  • 环境变量被子进程继承下去是一种默认行为,不受程序替换的影响,为什么?

通过地址空间可以让子进程继承父进程的环境变量数据

程序替换,只替换新程序的代码和数据,环境变量不会被替换!!! 

你可能感兴趣的:(Linux,linux,运维,服务器)