进程程序替换
替换原理
用fork创建子进程后执行的是和父进程相同的程序,但有可能在执行不同的代码分支,(但是在实际情况中,我们通常希望子进程和父进程执行不同的程序,来提高效率,所以才有程序替换),子进程往往要调用一种exec函数用来执行另一个程序,将代码和数据替换为可执行文件的代码和数据,环境变量并不改变。当进程的用户空间代码和数据完全被新程序替换,从新程序开始执行。调用exec并不创建新进程,所以调用exec前后的进程id并不改变。
特别的:进程程序并没有返回值,因为替换成功以后就不再换回来了,就执行新的程序,除非程序替换失败就返回-1。所以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[]);
函数第一列参数都表示将要调用谁,而第二列及以后的参数表示怎样执行,函数传参以NULL结尾。
命名理解
- l(list):表示参数采用列表,即命令行参数形式
- v(vector):参数用数组
- p(path):有p自动给搜索环境变量
- e(env):表示自己维护环境变量
事实上,只有execve是真正的系统调用函数,其他的五个函数底层都调用execve。