在进程的创建上UNIX/Linux采用了一个独特的方法,它将进程创建与加载一个新进程映象分离(system系统调用则将这两种操作合并)。这样的好处是有更多的余地对两种操作进行管理。
当我们创建了一个进程之后,通常将子进程替换成新的进程映象,这可以用exec系列的函数来进行。当然,exec系列的函数也可以将当前进程替换掉(不调用fork,直接调用exec)。
#include <unistd.h> extern 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 <unistd.h> #include <iostream> 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 <unistd.h> #include <iostream> 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 <unistd.h> #include <iostream> 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 */
原文地址:http://blog.csdn.net/zjf280441589/article/details/41090301