目录
[1 进程替换现象](#1 进程替换现象)
[2 进程替换原理](#2 进程替换原理)
[3 多进程](#3 多进程)
[4 其他进程替换方法](#4 其他进程替换方法)
1 进程替换现象

运行结果:

发现进程去执行ls命令
2 进程替换原理
使用fork创建子进程后执行的是和父进程相同的程序(但也有可能执行不同的代码分支),子进程往往要调用一种exec函数来执行另一个程序。
当进程调用一种exec函数时,该进程的用户空间代码和数据 完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
把代码和数据 替换 原进程的代码和数据
从被替换进程的角度:本质就是这个程序被加载到内存了;
如何加载:exec* 类似于一种Linux上的加载函数,涉及到系统调用。
进程替换成功场景:

进程替换后面的代码不再继续执行
exec*系列的函数执行完毕后,后续代码的不见了,是因为被替换了。
进程替换成功,就不会向后继续运行了,如果继续运行,说明一定是替换失败了!
进程替换失败场景:
下图展示替换失败的情况:

运行结果:

3 多进程
fork创建子进程,让子进程自己去替换,父进程wait

运行结果:

创建子进程,目的是让子进程去完成任务:
-
让子进程执行父进程代码的一部分;
-
让子进程执行一个全新的进程。
进程具有独立性,进程发生替换时(也就是让子进程执行一个全新的程序),会发生写时拷贝。
4 其他进程替换方法
使用所有的替换方法,并且认识函数参数的含义
execl中的l 表示list ,参数采用列表形式
execv中的v 表示vector,参数采用数组形式
execvp中的p 表示有p自动搜索环境变量PATH
execle中的e 表示自己维护环境变量
cpp
#include<stdio.h>
#include<stdlib.h>
#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);
//带v的参数用数组
execv("/bin/ps",argv);
execvp("ps",argv);
exit(0);
return 0;
}
path:表示要执行的程序需要带路径,也就是告诉函数怎么找到程序。先找到,在执行。
其余参数:就是在命令行中怎么执行,就这么传参
