进程程序替换

替换原理

用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。