exec族

这个一直没搞太明白,相识度高是一回事,不会用又是另外一回事儿。
因此今天又温故了一遍:web

为何须要exec函数?

fork子进程是为了执行新程序(fork建立了子进程后,子进程和父进程同时被OS调度执行,所以子进程能够单独的执行一个程序,这个程序宏观上将会和父进程程序同时进行)数组

能够直接在子进程的if中写入新程序打代码。但这样不够灵活,由于咱们只能把子进程程序的源代码贴过来执行(必须知道源代码,并且源代码太长了也很差控制)
使用exec族函数运行新的可执行程序。exec族函数能够直接把一个编译好的可执行程序直接加载运行。svg

有了exec族函数后,典型打父子进程程序是这样的:子进程须要运行的程序被单独编写、单独编译连接成一个可执行程序(hello)。主进程为父进程,fork建立了子进程后在子进程中exec来执行hello,达到父子进程分别作不一样程序同时(宏观上)运行的效果。函数

#include<unistd.h>

int execve(const char *path,char *const argv[],char *const envp[]);//这个是真正的系统调用
//如下的函数最后都是调用这个函数

int execl(const char *path,char *const argv,···);
int execlp(const char *file,char *const argv,···);
int execle(const char *path,char *const argv,···· ,char *const envp[]);
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv,);

exec函数族装入并运行程序path/file,并将参数arg0(arg1, arg2, argv[], envp[])传递给子程序,出错返回-1.spa

看一下后缀:.net

后缀 功能
l 但愿接收以逗号分隔的参数列表,列表以NULL指针做为结束标志
v 但愿接收到一个以NULL结尾的字符串数组的指针
p 是一个以NULL结尾的字符串数组指针,函数能够DOS的PATH变量查找子程序文件
e 函数传递指定参数envp,容许改变子进程的环境,无后缀e时,子进程使用当前程序的环境

下面我找到一些通俗易懂的栗子,算是让我明白了一点:指针

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{ 
 
   
  //以NULL结尾的字符串数组的指针,适合包含v的exec函数参数
  char *arg[] = { 
 
   "ls", "-a", NULL};
  
  /** * 建立子进程并调用函数execl * execl 中但愿接收以逗号分隔的参数列表,并以NULL指针为结束标志 */
  if( fork() == 0 )
  { 
 
   
    // in clild 
    printf( "1------------execl------------\n" );
    if( execl( "/bin/ls", "ls","-a", NULL ) == -1 )
    { 
 
   
      perror( "execl error " );
      exit(1);
    }
  }
  
  /** *建立子进程并调用函数execv *execv中但愿接收一个以NULL结尾的字符串数组的指针 */
  if( fork() == 0 )
  { 
 
   
    // in child 
    printf("2------------execv------------\n");
    if( execv( "/bin/ls",arg) < 0)
    { 
 
   
      perror("execv error ");
      exit(1);
    }
  }
  
  /** *建立子进程并调用 execlp *execlp中 *l但愿接收以逗号分隔的参数列表,列表以NULL指针做为结束标志 *p是一个以NULL结尾的字符串数组指针,函数能够DOS的PATH变量查找子程序文件 */
  if( fork() == 0 )
  { 
 
   
    // in clhild 
    printf("3------------execlp------------\n");
    if( execlp( "ls", "ls", "-a", NULL ) < 0 )
    { 
 
   
      perror( "execlp error " );
      exit(1);
    }
  }
  
  /** *建立子里程并调用execvp *v 望接收到一个以NULL结尾的字符串数组的指针 *p 是一个以NULL结尾的字符串数组指针,函数能够DOS的PATH变量查找子程序文件 */
  if( fork() == 0 )
  { 
 
   
    printf("4------------execvp------------\n");
    if( execvp( "ls", arg ) < 0 )
    { 
 
   
      perror( "execvp error " );
      exit( 1 );
    }
  }
  
  /** *建立子进程并调用execle *l 但愿接收以逗号分隔的参数列表,列表以NULL指针做为结束标志 *e 函数传递指定参数envp,容许改变子进程的环境,无后缀e时,子进程使用当前程序的环境 */
  if( fork() == 0 )
  { 
 
   
    printf("5------------execle------------\n");
    if( execle("/bin/ls", "ls", "-a", NULL, NULL) == -1 )
    { 
 
   
      perror("execle error ");
      exit(1);
    }
  }
  
  /** *建立子进程并调用execve * v 但愿接收到一个以NULL结尾的字符串数组的指针 * e 函数传递指定参数envp,容许改变子进程的环境,无后缀e时,子进程使用当前程序的环境 */
  if( fork() == 0 )
  { 
 
   
    printf("6------------execve-----------\n");
    if( execve( "/bin/ls", arg, NULL ) == 0)
    { 
 
   
      perror("execve error ");
      exit(1);
    }
  }
  return EXIT_SUCCESS;
}

本文分享 CSDN - 看,将来。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。code

相关文章
相关标签/搜索