替换原理
用
fork
创建子进程后执行的是和父进程相同的程序。
如果想要执行不同的代码分支或调用其他语言编写的程序,
子进程往往要调用一种
exec
函数以执行另一个程序。
当进程调用一种exec
函数时
,
该进程的用户空间代码和数据完全被新程序替换。
调用exec
并不创建新进程
,
所以调用
exec
前后该进程的
id
并未改变。
替换函数
其实有六种以
exec
开头的函数
,
统称
exec
函数
:
#include <unistd.h>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[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execve(const char *path, char *const argv[], char *const envp[]);
函数解释
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
- 如果调用出错则返回-1
- 所以exec函数只有出错的返回值而没有成功的返回值。
命名理解
这些函数原型看起来很容易混
,
但只要掌握了规律就很好记。
- l(list) : 表示参数采用列表
- v(vector) : 参数用数组
- p(path) : 有p自动搜索环境变量PATH
- e(env) : 表示自己维护环境变量
调用举例
#include <unistd.h>
int main()
{
char *const argv[] = {"ps", "-ef", NULL};
char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};
execl("/bin/ps", "ps", "-ef", NULL);
// 带p的,可以使用环境变量PATH,无需写全路径
execlp("ps", "ps", "-ef", NULL);
// 带e的,需要自己组装环境变量
execle("ps", "ps", "-ef", NULL, envp);
execv("/bin/ps", argv);
// 带p的,可以使用环境变量PATH,无需写全路径
execvp("ps", argv);
// 带e的,需要自己组装环境变量
execve("/bin/ps", argv, envp);
exit(0);
}
这些函数中,只有execve是真正的系统调用,其它五个函数最终都调用 execve