• 2.3 进程控制之exec函数族


    学习目标:学习使用exec函数族的重要的几个函数


     一、引言

    进程通过exec函数根据指定的文件名或目录名执行另一个可执行文件,当进程调用exec函数时,该进程的数据段、代码段和堆栈段完全被新程序替换,从新程序的启动例程开始执行。但调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

    1. 函数说明

    头文件:#include <unistd.h>

    函数原型:

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

    int execle(const char *path, const char *arg, ..., char *const envp[]);

     

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

     

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

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

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

     

    返回值:成功:无返回;失败:-1

     

    查找方式:前4个函数的查找方式都是完整的文件目录路径(即绝对路径),而最后两个函数(以p结尾的两个函数)可以只给出文件名,系统就会自动从环境变量“$PATH”所指出的路径中进行查找。

    参数传递方式:一种是逐个列举的方式(含有字母“l”),另一种是将所有参数整体构造成一个指针数组(含有字母“v”),然后将该数组的首地址当做参数传递给它,数组中的最后一个指针要求为NULL)

    环境变量:exec函数族使用了系统默认的环境变量,也可以传入指定的环境变量。这里以“e”结尾的两个函数就可以在envp[]中指定当前进程所使用的环境变量替换掉该进程继承的所有环境变量。

    p (path) 搜素file时使用path变量(文件名)

    l (list) 命令行参数列表

    v (vector) 使用命令行参数数组

    e (environment) 使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量

    例程:

    char *const argv[] = {"ps", "-o", "pid, ppid, session, tpgid, comm, NULL"};
    
    char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};
    
    execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
    
    execv("/bin/ps", argv);
    
    execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, envp);
    
    execve("/bin/ps", argv, envp);
    
    execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
    
    execvp("ps", argv);

    完整程序:第一个参数为该应用程序的名称

    1) execl()

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 
     4 int main(void)
     5 {
     6     pid_t pid = fork();
     7 
     8     if (pid == 0) {  
     9         execl("/work/material/linux-系统编程/day01/4-源代码/01_process_test/exec/output", "output", NULL);
    10     } else if (pid > 0) {
    11         printf("i'm parent pid = %d
    ", getpid());
    12     sleep(10);
    13     }
    14 
    15     return 0;
    16 }

    2) execlp()

     1 #include <stdlib.h>
     2 #include <unistd.h>
     3 #include <stdio.h>
     4 int main(int argc, char *argv[])
     5 {
     6     char *argvv[] = {"ls", "-l", "-F", "R", "-a", NULL};
     7     pid_t pid = fork();
     8     if (pid == 0) {
     9     execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
    10     //********下面不再运行***********//
    11         execl("/bin/ls", "ls", "-l", "-F", "-a", NULL);
    12         printf("I am child
    ");
    13         execv("/bin/ls", argvv);
    14         perror("execlp");
    15         exit(1);
    16     } else if (pid > 0) {
    17         sleep(2);
    18         printf("I am parent
    ");
    19     }
    20     return 0;
    21 }

     注意:一个进程一旦调用exec类函数,它本身就不再运行了。

  • 相关阅读:
    gitlab使用
    小程序顶部导航栏标题不居中
    mpvue中使用vant-weapp
    原生js实现轮播图
    vue无法检测数组的变动
    vue报错TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function
    vue绑定style使用需要添加浏览器引擎前缀的 CSS 属性
    《孙子算经》之"物不知数"题:中国剩余定理
    Java大数处理类:BigInteger类和BigDecimal类
    【转】操作系统典型调度算法
  • 原文地址:https://www.cnblogs.com/lxl-lennie/p/10216582.html
Copyright © 2020-2023  润新知