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

相關文章
相關標籤/搜索