首页 > 系统相关 >进程程序替换

进程程序替换

时间:2022-10-05 22:01:20浏览次数:50  
标签:execl NULL 程序 execpp ls 进程 include 替换

程序替换原理:

  • 1.将磁盘中的程序,加载如内存结构
  • 2.重新建立页表映射,谁执行程序替换,就重新建立谁的映射(子进程)

效果:让我们的父进程和子进程彻底分离,并让子进程执行一个全新的程序

子进程原来映射到父进程,现在子进程申请自己的物理内存,让子进程指向自己的数据段,和代码段,让父子进程彻底分离,这个过程叫进程程序替换。这个过程是没有产生新的进程


 

execl使用操作

头文件 <unistd.h>

execl共有7种接口,但都是对象接口的封装。调用execve

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 int main()
  5 {
  6 printf("---------------------------------");
  7 // execl("/usr/bin/pwd","pwd",NULL);                                                                                                                               
  8 
  9  execl("/usr/bin/ls","ls","-a","-l",NULL);
 10 printf("aaa");
 11 printf("aaa");
 12   return 0;
 13 }

在程序9行 进行了程序替换操作 看下实际运行效果

 

 可以看出  实际运行效果 后面的aaa并没有打印 为什么?

因为:执行了execl,程序就替换了,execl后面的代码也被替换了,早就不存在的。

替换成功了,程序就跑到了你写的路径下,比如此程序就到了ls的程序下,结束时,也是通过ls结束的。

而替换失败时,就会执行后面的代码

也就说明 成功不返回,失败返回-1

 

 1 #include<stdio.h>
    2 #include<stdlib.h>
    3 #include<unistd.h>
    4 
    5 int main()
    6 {
    8  pid_t id=fork();
    9  if(id==0)
   10  {
   20    execl("/usr/bin/ls","ls","-a","-l",NULL);                                                                                                                
   27    exit(1);
   28  }
   29  int statas=0;
E> 30  int ret=waitpid(id,&statas,0);
   31  if(ret==id)
   32    printf("父进程等待成功!\n");
   33 
   34   return 0;
   35 }

这段程序生成父子进程

让子进程去到新的进程去,父进程能否执行下面的代码?

 

 可以发现,是可以执行下面的代码的?

为什么?

子进程替换不会影响父进程,因为进程具有独立性。

当进程替时,代码和数据都发生了写实拷贝完成父子的分离

 

execv

execv和execl的区别 只有传参方式不同

 #include<stdio.h>
    2 #include<stdlib.h>
    3 #include<unistd.h>
    4 
    5 int main()
    6 {
    7   extern char**environ;
    8  pid_t id=fork();
    9  if(id==0)
   10  {
   11   char *const argv_[]=
   12   {
   13     (char*)"ls",                                                                                                                                                 
   14     (char*)"-a",
   15     (char*)"-l",
   16     NULL
   17   };
   18 
   19   execv("/usr/bin/ls",argv_);
   27    exit(1);
   28  }
   29  int statas=0;
E> 30  int ret=waitpid(id,&statas,0);
   31  if(ret==id)
   32    printf("父进程等待成功!\n");
   33 
   34   return 0;
   35 }

execv传数组 execl传列表

 

execlp("ls","ls","-a","-l",NULL);

execlp也是一样的效果,只不过execlp要传的指针在PATH中时 可以不用写绝对路径

 

execl可以完成一种语言对另一种语言的调用

只不过这两种语言需要线允许起来即可

因为makefile的普通命名只能单次生成单个程序

利用all可以同时完成多个程序

.PHONY:all
  2 all:execpp exec

all后依赖的是能执行的程序 既完成编译过后的可执行文件的名称

随后我们再实现一个cpp文件

 #include<iostream>
  2 #include<stdlib.h>
  3 using namespace std;
  4 
  5 int main()
  6 {                                                                                                                                                               
 11  cout<<"C++"<<endl;
 12  cout<<"C++"<<endl;
 13  cout<<"C++"<<endl;
 14  cout<<"C++"<<endl;
 15  cout<<"C++"<<endl;
 16  cout<<"C++"<<endl;
 17  cout<<"C++"<<endl;
 18   return 0;
 19 }

 

   22   execl("./execpp","execpp",NULL);                                                                                                                               
   23  //execl("/home/moxuan/m10d5/execpp","execpp",NULL);

在原来exec.c的文件内用execl实现对cpp文件的调用(两条代码选其中一条均可,效果一样)

随后生成这两个可执行文件。

只执行exec.c

 

可以发现,两个文件都运行了,就实现了一种语言对另一种语言的调用 这里是c语言调用c++

 

添加环境

在从cpp内实现此条代码

cout<<"MYPATH : "<<getenv("MYPATH")<<endl;

在c中 实现此条代码

  char *const env_[]={ (char*)"MYPATH=you can see me!",NULL};
      execle("./execpp","execpp","env");   

运行效果

 

发现MYPATH后并未打印 因为添加环境变量是覆盖式

 

另一种方法

extern char**environ;
execle("./execpp","execpp",NULL,environ);

在外设置环境变量

 

 随后执行两种文件

 

 可以发现不会有打印不出的结果,而是两种环境遍历均打印


 

标签:execl,NULL,程序,execpp,ls,进程,include,替换
From: https://www.cnblogs.com/LonelyMoNan/p/16756529.html

相关文章