进程程序替换
替换原理
fork创建子进程执行的是和父进程相同的程序(也有可能是某个分支),通常fork出的子进程是为了完成父进程所分配的任务,所以子进程通常会调用一种exec函数(六种中的任何一种)来执行另一个任务。当进程调用exec函数时,当前用户空间的代码和数据会被新程序所替换,该进程就会从新程序的启动历程开始执行。在这个过程中没有创建新进程,所以调用exec并没有改变进程的id。替换过程(图解)
替换函数(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. 这些函数如果调用成功,则加载的新程序从启动代码开始执行,不再返回
2. 如果调用出错返回-1
3. exec系列函数成功调用没有返回值,调用失败才有返回值命名规律
1. l(list):表示参数采用列表
2. v(vector):表示参数采用数组
3. p(path):自动搜索环境变量PATH
4. e(env):自己维护环境变量(自己组装环境变量)
函数名 | 参数格式 | 是否带路径 | 是否使用当前环境变量 |
---|---|---|---|
execl | 参数列表 | 否 | 是 |
execlp | 参数列表 | 是 | 是 |
execle | 参数列表 | 否 | 否 |
execv | 参数数组 | 否 | 是 |
execvp | 参数数组 | 是 | 是 |
execve | 参数数组 | 否 | 否 |
* 六个函数之间的关系
事实上,只有execve是系统调用,其他五个最终都调用execve。
- 拓展:写简易shell的需要循环的步骤
- 获取命令行
- 解析命令行
- 创建子进程(fork)
- 进行程序替换—替换子进程(execve)
- 父进程等待子进程退出(wait)