Linux下的exec函数族

Linux下的exec函数族,第1张

Linux下的exec函数族 引入

  创建子进程后,我们并不希望子进程执行父进程后续相同的内容,这时我们可以用exec函数族进行子进程的执行内容替换。

exec函数族

Linux下的exec函数族,是指6个以exec开头的函数。分别是

int execl(const char *path,const char *arg,...)
int execv(const char *path,char *cosnt arg[])
int execle(const char *path,const char *arg,...,char *const envp[])
int execve(const char *path,char *const argv[],char *const envp[])
int execlp(const char *file, const char *arg,...)
int execvp(const char *file, char *const argv[]);

复习:牢记const修饰的是谁?指针标记的优先级低于偏移符号[]。
const char *p:p是一个指针,指向常字符类型
char const *p:同上,const修饰的是*p
char * const p:p是一个常指针,指向字符类型。const修饰的是p
char *p[]:p是一个数组,其内容是字符指针
char (*p)[]:p是一个指针,指向的内容是字符数组(字符串)
char * const p[]:p是一个数组,数组的内容是常字符指针

我们介绍最常用的第一个程序:

int execl(const char *path,const char *arg,...)
执行原理

为什么说exec函数族可以使子进程执行不同的程序呢?
——“换核不换壳”:进程在调用exec函数时,进程用户空间的代码和数据空间的代码会完全被新的替代。也就是说原有的text和data会被替换掉,但是调用exec函数并不会产生新的进程,也不会改变PID。
  直白地讲,就是原有的箱子不变。但是调用exec函数后,其中原有的苹果被换成了梨。

使用场景
  1. 进程认为自己不能再为系统和用户作出任何贡献时,就可以调用任何exec函数族让自己重生
  2. 如果一个进程想要执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。

我们依旧举一些例子:

//main.c文件
#include
#include
#include

int main(void)
{   
    //int execl(const char *pathname, const char *arg, ...
    //                   );
    //第一个参数是要执行的执行文件的路径(包含文件名),第二个是要执行文件的文件名
    //之后的变长参数就是要带的参数。最后要以(char *)NULL作为最后一个参数
    pid_t pid;
    pid=fork();
    if(pid<0)
    {   
        printf("process create failed!");
    }   
    else if(pid == 0)
    {   
        printf("This is child process!");
        printf("PID=%d parent PID=%dn",getpid(),getppid());
        execl("/home/czc/Desktop/LinuxExp/process/subproc","subproc",(char *)NULL);
        exit(1);
    }   
    else
    {   
        printf("This is parent process!");
        printf("PID=%d Its child PID=%dn",getpid(),pid);
    }
    printf("This is father process remaining part!n");
    return 0;
}

//./subproc.c文件
#include
int main(void)
{
    printf("enter a new subProcess!n");
    return 0;
}

调用main.c编译的可执行文件结果如下:

可以发现,父进程剩下的部分,子进程并没有执行。子进程在调用exec函数族后,就只执行subproc.c编译出来的可执行文件了。这里使用exit(1)的目的只是在exec调用失败后,也主动结束子进程。

命令即可执行文件

  之前已经提到,Linux下的命令就是可执行文件。那么同样地,我们在调用exec函数族时不仅可以使用我们自己编写的可执行文件,也可以调用系统命令(也就是系统自带的可执行文件)。我们对上面的C源文件稍作修改:

//main.c文件
#include
#include
#include

int main(void)
{   
    //int execl(const char *pathname, const char *arg, ...
    //                   );
    //第一个参数是要执行的执行文件的路径(包含文件名),第二个是要执行文件的文件名
    //之后的变长参数就是要带的参数。最后要以(char *)NULL作为最后一个参数
    pid_t pid;
    pid=fork();
    if(pid<0)
    {   
        printf("process create failed!");
    }   
    else if(pid == 0)
    {   
        printf("This is child process!");
        printf("PID=%d parent PID=%dn",getpid(),getppid());
        //ls命令在路径/bin/下
        execl("/bin/ls","ls","-al",(char *)NULL);
        exit(1);
    }   
    else
    {   
        printf("This is parent process!");
        printf("PID=%d Its child PID=%dn",getpid(),pid);
    }
    printf("This is father process remaining part!n");
    return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5623976.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存