介绍
fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。(通过exec系列函数可以更加方便的指定程序名而不需要手工去修改程序的argv[0]和prctl函数去操控)
#include <unistd.h>
extern char **environ;
//带l的表示list每个参数的传递是通过list的方式传递进去的
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
//带v的表示vector参数的传递是通过vector的方式传递的,其中p代表从环境变量PATH中查找,e从传递的环境变量中获取。
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[]);
例子
进程调用exec函数替换进程映像
// prog.cpp
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
char* const prog[3] =
{
"test_prog",//modify name to test_prog
"20",// the argv...
NULL // the last must NULL
};
printf("start call exec function current pid [%d]\n",getpid());
execvp("sleep",prog);
printf("end call exec function\n");// can not output
return 0;
}
子进程拉起进程父进程等待子进程结束
// prog_sub.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
char* const prog[3] =
{
"test_prog_sub",//modify name to test_prog_sub
"10",// the argv...
NULL // the last must NULL
};
pid_t pid = fork();
if(pid<0)
{
printf("fork child process error\n");
exit(-1);
}
else if(pid==0)
{
printf("start call exec function current pid [%d]\n",getpid());
execvp("sleep",prog);
}
int status=0;
do {
pid_t child_pid = wait(&status);
if(child_pid==-1)
{
printf("wait pid error \n");
}
if(WIFEXITED(status))
{
printf("child process end that pid [%d] exit code [%d]",child_pid,WEXITSTATUS(status));
}
} while((!WIFEXITED(status) && !WIFSIGNALED(status)));
return 0;
}