进程控制3(进程替换)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liu_zhen_kai/article/details/81911364

进程替换

在fork之后,产生的子进程会拥有和父进程相同的代码段和数据段,执行父进程相同的公共代码,但是多数情况下我们不会让子进程做与父进程相同的工作,这样就会用到进程替换的概念。
进程替换可以使用exec函数族来完成替换工作

exec族函数在man手册的资料:

       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[]);

进程一旦被替换,则从新的程序main函数开始运行起来,所有的参数列表,环境变量都可以由用户自己定义, 而且被替换成功的进程不会执行原函数下面的代码

在man手册中的五个exec族函数分别代表着不同的用法,可以这样来记忆:

  • 当结尾有l (list),代表着需要平铺(也就是每个都输入)所有的新进程中需要用到的命令行参数(也就是main函数的第二个参数argv[ ])以NULL结尾
  • 当结尾有p,代表操作系统自动捕获环境变量PATH(路径),则不需要手动输入路径,仅仅输入文件名即可
  • 当结尾带有v,则可定义char*型指针数组存放新进程需要的参数列表,传值只传一个char*地址即可
  • 当结尾带有e,则可以由用户自己定义其新进程的环境变量(但是这个新的环境变量不会影响系统的环境变量,仅在该进程中使用)
  • If any of the exec() functions returns, an error will have occurred. The return value is -1, and errno will be set to indicate the error(替换错误返回-1,正确没有返回值)

下面对每个函数的用法举例
execl() :

  1 //example for execl
  2 
  3 #include <unistd.h>
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 
  8 
  9 int main(void)
 10 {
 11     int ret;
 12     printf("this is the function execl : \n");
 13 
 14     ret = execl("/bin/pwd", "pwd", NULL);//替换到 pwd 命令
 15 
 16     printf("exec failed\n");    // 如果进程运行到这里代表替换失败
 17     return 0;
 18 }
~                        

运行结果如下

[liu@localhost ecexl]$ cc execl.c -o execl
[liu@localhost ecexl]$ ./execl 
this is the function execl : 
/home/liu/boke/03/ecexl

可见运行结果在进程被替换成功,而且进程不会回到原来的代码继续执行,而是在新的程序中直接返回


execlp():

  1 //example for execlp
  2 
  3 #include <unistd.h>
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 
  8 
  9 int main(void)
 10 {
 11     int ret;
 12     printf("this is the function execlp : \n");
 13 
 14     ret = execlp("pwd", "pwd", NULL); //不需要加路径,只需要加文件名
 15 
 16     printf("exec failed]n");
 17     return 0;
 18 }              

运行结果:

[liu@localhost execlp]$ ./execlp 
this is the function execlp : 
/home/liu/boke/03/execlp

execle():

  1 //example for execle
  2 //execle.c
  3 #include <stdio.h>
  4 #include <unistd.h>
  5 #include <stdlib.h>
  6 
  7 
  8 int main(int argc, char* argv[], char* env[])
  9 {
 10     printf("HOME=%s\n", getenv("HOME"));
 11     printf("USER=%s\n", getenv("USER"));
 12     //打印系统默认的环境变量
 13     char* ENV[] = {"HOME=XI'AN", "USER=LIU"};
 14     //给定新的进程环境变量
 15     int ret = execle("./tmp", "tmp", NULL,ENV);
 16     
 17     printf("execle failed\n");
 18     return 0;
 19 }
  0//tmp.c
  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 
  5 
  6 int main(int argc, char* argv[], char* env[])
  7 {
  8     printf("this is function tmp\n");
  9     printf("HOME=%s\n", getenv("HOME"));
 10     printf("USER=%s\n", getenv("USER"));
 11     return 0;
 12 }

运行结果

[liu@localhost execle]$ ./tmp 
this is function tmp
HOME=/home/liu
USER=liu
[liu@localhost execle]$ ./execle 
HOME=/home/liu
USER=liu
this is function tmp
HOME=XI'AN
USER=LIU

被替换时环境变量改变为设置的值,但是直接运行不会改变环境变量

execv():

  1 //example for execv
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <unistd.h>
  6 
  7 
  8 int main(void)
  9 {
 10     char* argv[] = {"ls", "-a", "-l", NULL};
 11     printf("this is main function :\n");
 12 
 13     execv("/bin/ls", argv);
 14 
 15     printf("execv error\n");
 16     return 0;
 17 }

运行结果

[liu@localhost execv]$ ./execv 
this is main function :
total 20
drwxrwxr-x. 2 liu liu 4096 Aug 21 10:12 .
drwxrwxr-x. 6 liu liu 4096 Aug 21 10:08 ..
-rwxrwxr-x. 1 liu liu 4836 Aug 21 10:12 execv
-rw-rw-r--. 1 liu liu  245 Aug 21 10:12 execv.c

execvp():

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 
  5 
  6 int main(void)
  7 {
  8     char *argv[] = {"ls", "-l", NULL};
  9 
 10     execvp("ls", argv);
 11 
 12     printf("execvp error\n");
 13     return 0;
 14 }               

运行结果

[liu@localhost execvp]$ cc execvp.c -o execvp
[liu@localhost execvp]$ ./execvp 
total 12
-rwxrwxr-x. 1 liu liu 4802 Aug 21 10:16 execvp
-rw-rw-r--. 1 liu liu  178 Aug 21 10:16 execvp.c

猜你喜欢

转载自blog.csdn.net/liu_zhen_kai/article/details/81911364