方法
fork函数可以创建子进程,子进程会以父进程为模版拷贝PCB,并且执行父进程的代码,但是有一种情况我们并不想子进程执行父进程的代码,而是想让子进程去执行其它程序,这时就需要用到exec系列函数了。
参数:
path:目标程序的路径(绝对路径or相对路径)
file:目标程序名字,函数会根据环境变量PATH中的路径寻找
arg: 目标程序的名字
...: 目标程序的选项,以NULL结尾
envp:传入环境变量(系统or自定义)
argv:就是把arg和...放入到一个指针数组中
返回值:
只有错误的时候返回-1,并设置errno以指示错误
execl
pid_t id = fork();
if(id == 0)
{
execl("/usr/bin/ls", "ls", "--color=auto", "-a", "-l", NULL);
exit(0);
}
execlp
pid_t id = fork();
if(id == 0)
{
execl("ls", "ls", "--color=auto", "-a", "-l", NULL);
exit(0);
}
execle
pid_t id = fork();
if(id == 0)
{
putenv("myenv=12345678");//将自己的环境变量导入到系统环境变量中
extern char **environ;//系统环境变量
execle("ls", "ls", "--color=auto", "-a", "-l", NULL, environ);
exit(0);
}
execv
pid_t id = fork();
if(id == 0)
{
char *const argv[64] = {
"ls",
"--color=auto",
"-a",
"-l",
NULL
}
execv("/usr/bin/ls", argv);
exit(0);
}
execvp
pid_t id = fork();
if(id == 0)
{
char *const argv[64] = {
"ls",
"--color=auto",
"-a",
"-l",
NULL
}
execv("ls", argv);
exit(0);
}
execvpe
pid_t id = fork();
if(id == 0)
{
char *const argv[64] = {
"ls",
"--color=auto",
"-a",
"-l",
NULL
}
putenv("myenv=12345678");//将自己的环境变量导入到系统环境变量中
extern char **environ;//系统环境变量
execv("ls", argv, envp, environ);
exit(0);
}
原理
fork创建子进程后,父子进程两份PCB,都指向同一份程序。当子进程使用exec系列函数时,会从磁盘加载新的程序代码和数据,子进程会指向该新程序,同时子进程的进程地址空间里的数据会初始化为新程序的,环境变量不变、pid不变。