【Linux】进程替换exec

文章目录

是什么? 

编写示例使用exec函数替换进程映像

exec与fork的结合使用


一、概念 

  • 有时我们需要在子进程中执行其他程序,即替换当前进程映像,这就需要使用如下exec系列函数之一:
  • #include<unisted.h>
    extern char** environ;
     
    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,const char* argv[]);
    int execvp(const char * file,const char* argv[]);
    int exeve(const char * path,const char* argv[],char* const envp[]);
  • path参数指定可执行文件的完整路径,file参数可以接受文件名,该文件的具体位置则在环境变量path中搜寻arg接收可变参数,argv则接收参数数组,他们都会被传递给新程序(path或file指定的程序)的main函数。envp参数用于设置新程序的环境变量。如果未设置它,则新程序将使用由全局变量environ指定的环境变量。
  • 一般情况下,exec函数是不返回的,除非出错。出错时返回-1,并设置errno。如果没出错,则源程序中exec调用之后的代码都不会执行,因此此时源程序已经被exec的参数指定的程序完全替换(把偶哦代码和数据)。
  • exec函数不会关闭源程序打开的文件描述符,除非文件描述符被设置了类似SOCK_CLOEXEC的属性。
     

二、编写示例使用exec函数替换进程映像

  • 如下,把test替换为ps路径
  • 首先查找ps路径
  • 然后编写test.c文件,执行命令
    • 执行结果可发现输出的pid=1863和-f参数状态中的pid一致,可验证替换成功 

test.c内部代码:

  • 1.按照int execl(const char * path,const char* arg,...);的库标准写:execl("/usr/bin/ps","ps","-f",(char *)0);  // /usr/bin/ps: 文件路径;ps:程序名;-f:参数;((char *)0):以空结尾,类型强转 

  • 2.按照int execlp(const char * file,const char* arg,...);的库标准写:execlp("ps","ps","-f",(char *)0);//ps:程序名;-f:参数;((char *)0):以空结尾,类型强转

    • execlp不需要再写环境变量,系统可自己在path路径下查宅,如下所示示例PATH路径:

  • 3.按照int execle(const char * path,const char* arg,...,char* const envp[]);的库标准写: execle("/usr/bin/ps","ps","-f",(char *)0,envp); // /usr/bin/ps: 文件路径;ps:程序名;-f:参数;(char *)0:以空结尾,类型强转;envp:采用main的环境变量;

  • 4.按照int execv(const char * path,const char* argv[]); 的库标准写: char *myargv[]={"ps","-f",0};execv("/usr/bin/ps",myargv);// /usr/bin/ps: 文件路径;myargv:存放参数的数组;

  • 5.按照int execvp(const char * file,const char* argv[]); 的库标准写:char *myargv[]={"ps","-f",0}; execvp("ps",myargv); // ps: 程序名;myargv:存放参数的数组;

  • 6.按照int exeve(const char * path,const char* argv[],char* const envp[]);的库标准写:char *myargv[]={"ps","-f",0}; execve("/usr/bin/ps",myargv,envp);// /usr/bin/ps: 文件路径;myargv:存放参数的数组;envp:采用main的环境变量;

  • 注意,当运行成功时,执行完exec函数会直接执行exit,如果失败会开始执行exec和eexit之间的代码(可以在这之间输出“execl error”的提醒)

三、exec与fork的结合使用

问:linux上创建新进程的方式是?

答:fork()+exec()

举例解释

  • 例1实现当前主程序复制产生一个子进程,子进程用程序ps替换自身:
    • pid==0:子进程;pid==-1fork失败
    • getpid()得到子进程PID;getppid()得到父进程PPID
  • 执行结果分析:
    • 第一步打印了父进程和子进程
    • fork()复制出子进程,打印子进程
    • 子进程进行替换ps,在下图中倒数第二行和倒数第一行的PID也可看出ps -f(5249)是main(5248)的子进程。

  • 例2当前主程序复制产生一个子进程,子进程用新程序"b"替换自身
  • text1.c:
  • b.c:

  • 执行结果分析:
  • 在text1执行时,执行了第一步,打印main pid;
  • 然后复制子进程,子进程用新程序"b"替换自身
  • 在b进程内:打印了参数个数:4,参数依次为text1.c数组myargv中写的:b,hello,abc,123,后面打印的就是环境变量..
  • 子进程结束,父进程获取退出码,wait(NULL)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值