进程程序替换

目录

替换原理

通过代码看现象

  原理解释

代码换成多进程版 

 使用替换方法并了解含义

函数解释

命令理解 

替换原理

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

通过代码看现象

linux下执行以下代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
    printf("testexec ... begin!\n");
    execl("/usr/bin/ls","ls","-l","-a",NULL);
    printf("testexec ... end!\n");
    return 0;
}

其实有六种以exec开头的函数,统称exec函数:

#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 execvpe(const char *file, char *const argv[],char *const envp[]);

  原理解释

所以只打印了第一个printf,用ls替换了老的代码和数据,走到第二个printf时已经执行exec了早就替换了所以看不到第二个printf 。过程中没有创建新进程,只不过用老进程的壳子执行新程序的代码。exec*函数执行完毕后,后续的代码不见了因为被替换。
所以不用关心execl函数的返回值因为只要替换成功就不会往后执行,反之只要继续执行了那么就是没替换成功则替换失败。

替换失败

代码换成多进程版 

fork创建子进程,让子进程自己去替换,父进程在等待。

创建子进程:让子进程完成任务:1.让子进程执行父进程代码的一部分 2.让子进程执行一个全新的程序。
子进程程序替换后不影响父进程因为进程具有独立性,会发生写时拷贝在内存开辟空间覆盖代码和数据

 使用替换方法并了解含义

函数解释

1. 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。

2. 如果调用出错则返回-1

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

命令理解 

1. l(list) : 表示参数采用列表

2. v(vector) : 参数用数组

3. p(path) : 有p自动搜索环境变量PATH

4. e(env) : 表示自己维护环境变量

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

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

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

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

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


makefile:

  1 .PHONY:all
  2 all:myprogram testexec                                                                                                                                   
  3 
  4 testexec:testvim.c
  5         gcc -o $@ $^ -std=c99
  6 myprogram:myprogram.cc
  7         g++ -o $@ $^ -std=c++11
  8 .PHONY:clean
  9 clean:
 10         rm -rf mytest.exe
    1 #include<iostream>                                                                                                                                     
    2 #include<unistd.h>
    3 using namespace std;
    4 int main (int argc,char*argv[],char*env[])
    5 {
    6     int i=0;
    7     for(;argv[i];i++){
    8         printf("argv[%d] : %s\n",i,argv[i]);
    9     }
   10     printf("-----------------------------\n");
   11     for(i=0;env[i];i++){
   12         printf("env[%d] : %s\n",i,argv[i]);
   13     }
   14     printf("-----------------------------\n");
   15     cout<<"hello c++,i am a program"<<getpid()<<endl;
   16     cout<<"hello c++,i am a program"<<getpid()<<endl;
   17     return 0;
   18 }
1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/wait.h>
  6 #include<sys/types.h>
  7 int main()
  8 {
  9     printf("testexec begin \n");
 10     pid_t id=fork();
 11     if(id==0){
 12         char *const argv[]={
 13         (char*)"myprogram",
 14         (char*)"-a",
 15         (char*)"-b",
 16         NULL
 17 
 18         };
 19         char*const envp[]={
 20         (char*)"HAHA=1111",
 21         (char*)"HEHE=2222",
 22         NULL
 23         };
 24         printf("child pid:%d\n",getpid());
 25         sleep(2);
 26         execvpe("./myprogram",argv,envp);                                                                                                                
 27         exit(-1);
 28     }
 29     int status=0;
 30     pid_t rid=waitpid(id,&status,0);
 31     if(rid>0){
 32         printf("farther wait succes ,child exit code:%d\n",WEXITSTATUS(status));
 33     }
 34     printf("testexec end!\n");
 35     return 0;
 36 }



当然也可以传bash进程传给父进程的environ

 通过exec*函数可以让子进程执行另一个程序。也可以让子进程执行另一个可执行文件

execl("./program","program",NULL);     program为另一个程序的可执行文件

但是值得注意的是只有execve才是系统调用,执行的是二号手册(man)


可以理解为其他exec*函数接口底层都调用execve系统调用。将其他exec*函数封装是为了适应不同的应用场景。

  • 38
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangsir.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值