Linux下多进程编程之exec函数语法及使用实例

exec函数族

1)exec函数族说明

fork()函数用于创建一个子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的进程如何执行呢?exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行的脚本文件。

在Linux中使用exec函数族主要有两种情况: ●当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用exec函数族中的任意一个函数让自己重生。 ●如果一个进程想执行另一个程序,那么它就可以调用fork()函数新建一个进程,然后调用exec函数族中的任意一个函数,这样看起来就像通过执行应用程序而产生了一个新进程(这种情况非常普遍)。

2)exec函数族语法

实际上,在Linux中并没有exec()函数,而是有6个以exec开头的函数,它们之间的语法有细微差别,本书在后面会详细讲解。

表2列举了exec函数族的6个成员函数的语法。

表2 exec函数族成员函数语法

所需头文件#include <unistd.h>

函数原型int execl(const char *path, const char *arg, …)

int execv(const char *path, char *const argv[])

int execle(const char *path, const char *arg, …, char *const envp[])

int execve(const char *path, char *const argv[], char *const envp[])

int execlp(const char *file, const char *arg, …)

int execvp(const char *file, char *const argv[])

函数返回值-1:出错

这6个函数在函数名和使用语法的规则上都有细微的区别,下面就从可执行文件查找方式、参数传递方式及环境变量这几个方面进行比较。 ●查找方式。读者可以注意到,表2中的前4个函数的查找方式都是完整的文件目录路径,而最后两个函数(也就是以p结尾的两个函数)可以只给出文件名,系统就会自动按照环境变量“$PATH”所指定的路径进行查找。 ●参数传递方式。exec函数族的参数传递有两种方式:一种是逐个列举的方式,而另一种则是将所有参数整体构造指针数组传递。在这里是以函数名的第5位字母来区分的,字母为“l”(list)的表示逐个列举参数的方式,其语法为const char *arg;字母为“v”(vertor)的表示将所有参数整体构造指针数组传递,其语法为char *const argv[]。读者可以观察execl()、execle()、execlp()的语法与execv()、execve()、execvp()的区别,它们的具体用法在后面的实例讲解中会具体说明。

这里的参数实际上就是用户在使用这个可执行文件时所需的全部命令选项字符串(包括该可执行程序命令本身)。要注意的是,这些参数必须以NULL结束。 ●环境变量。exec函数族可以默认系统的环境变量,也可以传入指定的环境变量。这里以“e”(environment)结尾的两个函数execle()和execve()就可以在envp[]中指定当前进程所使用的环境变量。

表3再对这6个函数中的函数名和对应语法做了一个小结,主要指出了函数名中每一位所表明的含义,希望读者结合此表加以记忆。

表3 exec函数名对应含义

前4位统一为:exec

第5位l:参数传递为逐个列举方式execl、execle、execlp

v:参数传递为构造指针数组方式execv、execve、execvp

第6位e:可传递新进程环境变量execle、execve

p:可执行文件查找方式为文件名execlp、execvp

事实上,这6个函数中真正的系统调用只有execve(),其他5个都是库函数,它们最终都会调用execve()这个系统调用。在使用exec函数族时,一定要加上错误判断语句。exec很容易执行失败,其中最常见的原因有: ●找不到文件或路径,此时errno被设置为ENOENT。 ●数组argv和envp忘记用NULL结束,此时errno被设置为EFAUL。 ●没有对应可执行文件的运行权限,此时errno被设置为EACCES。

3)exec使用实例

下面的第一个示例说明了如何使用文件名的方式来查找可执行文件,同时使用参数列表的方式。这里用的函数是execlp()。

/* execlp.c */ #include <unistd.h> #include <stdio.h> #include <stdlib.h>int main() { if (fork() == 0) { /* 调用execlp()函数,这里相当于调用了“ps –ef”命令 */ if ((ret = execlp(“ps”, “ps”, “-ef”, NULL)) < 0) { printf(“Execlp error\n”); } } }

用积极的拼搏迎接雨后的彩虹,相信自己

Linux下多进程编程之exec函数语法及使用实例

相关文章:

你感兴趣的文章:

标签云: