1、exec族函数及实战
1.1、为什么需要exec函数 (1)fork子进程是为了执行新程序(fork创建子进程后,子进程和父进程同时被OS调度执行,因此子进程可以单独的执行一个程序,这个程序宏观上将会和父进程程序同时进行 ) (2)可以直接在子进程的if中写入新程序的代码。这样可以,但是不够灵活,因为我们只能把子进程程序的源代码贴过来执行(必须知道源代码,而且源代码太长了也不好控制),譬如说我们希望子进程来执行ls-la命令就不行了(没有源代码,只有编译好的可执行程序) (3)使用exec运行新的可执行程序(exec族函数可以直接把一个编译好的可执行程序直接加载运行) (4)我们有了exec族函数后,我们典型的父子进程程序是这样的:子进程需要运行的程序被单独编写、单独编译链接成一个可执行程序(eg:hello),(项目是一个多进程项目)主程序为父进程,fork创建了子进程后在子进程中exec来执行hello,达到了父子进程分别做不同程序同时(宏观上)运行的效果。 1.2、exec族的6个函数介绍 (1)execl和execv 这两个函数是最基本的exec函数,都可以用来执行一个程序,区别是传参的格式不同。execl是把参数列表(本质上是多个字符串,必须以NULL结尾)依次排列而成(l其实就是list的缩写),execv是把参数列表事先放入一个字符串数组中,再把这个字符串数组传给execv函数。 (2)execlp和execvp 这两个函数在上面两个基础上加了p,较上面两个来说,区别是:上面两个执行程序时必须指定可执行程序的全路径(如果exec没有找到path这个文件则直接报错),而加了p的传递可以使file(也可以是path,只不过兼容了file。加了p的这两个函数会首先去找file,如果找到则执行,如果没找到则会去环境变量PATH所指定的目录下去找,如果找到则执行,如果没找到则报错) (3)execle和execvpe 这两个函数基于exec加了e,函数的参数列表中也多了一个字符串数组envp形参,e就是environment环境变量的意思,和基本版本的exec的区别就是:执行可执行程序时会多传一个环境变量的字符串数组给待执行的程序 1.3、exec实战 (1)使用execl运行ls -l -a
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
pid_t pid = -1;
pid = fork();
if(pid > 0)
{
printf("parent, 子进程id = %d.\n", pid);
}
else if(pid == 0)
{
execl("/bin/ls", "ls", "-a", "-l", NULL);
return 0;
}
else
{
perror("fork");
return -1;
}
return 0;
}
(2)使用execv运行ls -l -a
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
pid_t pid = -1;
pid = fork();
if(pid > 0)
{
printf("parent, 子进程id = %d.\n", pid);
}
else if(pid == 0)
{
char * const arg[] = {"ls", "-l", "-a", NULL};
execv("/bin/ls", "ls", "-a", "-l", NULL);
return 0;
}
else
{
perror("fork");
return -1;
}
return 0;
}
|