這個一直沒搞太明白,相識度高是一回事,不會用又是另外一回事兒。
因此今天又溫故了一遍: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