在進程的創建上UNIX/Linux采用了一個獨特的方法,它將進程創建與加載一個新進程映象分離(system系統調用則將這兩種操作合並)。這樣的好處是有更多的余地對兩種操作進行管理。
當我們創建了一個進程之後,通常將子進程替換成新的進程映象,這可以用exec系列的函數來進行。當然,exec系列的函數也可以將當前進程替換掉(不調用fork,直接調用exec)。
#includeextern char **environ; int execl(const char *path, const char *arg, ...); //L:命令列表 int execlp(const char *file, const char *arg, ...); //p:在當前環境變量PATH下進行 int execle(const char *path, const char *arg, ..., char * const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char *file, char *const argv[], char *const envp[]); int execve(const char *filename, char *const argv[], char *const envp[]);
說明:
execl,execlp,execle(都帶“l”)的參數個數是可變的,參數以必須一個空指針結束。
execv和execvp的第二個參數是一個字符串數組(“v”代表“vector”,字符串數組必須以NULL結尾),新程序在啟動時會把在argv數組中給定的參數傳遞到main。
名字最後一個字母是“p”的函數會搜索PATH環境變量去查找新程序的可執行文件。如果可執行文件不在PATH定義的路徑上,就必須把包括子目錄在內的絕對文件名做為一個參數傳遞給這些函數
/*總結:l代表可變參數列表,p代表在path環境變量中搜索file文件。envp代表環境變量*/
#include#include using namespace std; int main() { execlp("/bin/pwd","/bin/pwd",NULL); //execlp("ls","ls","-l",NULL); cout << "After fork..." << endl; return 0; }
int main() { char *const args[] = { (char *)"/bin/date", (char *)"+%F", NULL }; execve("/bin/date",args,NULL); cout << "After fork..." << endl; return 0; }
//main.cpp #include#include using namespace std; int main() { cout << "In main, pid = " << getpid() << endl; char *const environ[] = { "AA=11", "BB=22", "CC=33", NULL }; execle("./hello","./hello",NULL,environ); //當environ填為NULL時,則什麼都不傳遞 cout << "After fork..." << endl; return 0; } //hello.cpp #include #include using namespace std; extern char **environ; int main() { cout << "In hello, pid = " << getpid() << endl; cout << "environ:" << endl; for (int i = 0; environ[i] != NULL; ++i) { cout << "\t" << environ[i] << endl; } }
/* In main, pid = 3572 //PID保持不變 In hello, pid = 3572 environ: AA=11 BB=22 CC=33 */