PCB有什么用:PCB描述了程序的运行过程
为什么创建子进程:为了完成一个任务
进程替换就是想让创建出来的子进程执行全新的程序
程序就是磁盘上的文件
- 程序在哪,先要找到程序的路径
- 如何执行,程序可能携带选项去执行
进程程序替换:
替换正在运行的程序,让正在运行的进程执行新程序;
进程程序替换原理及过程:
- 程序运行起来时是一个PCB,里面有一个变量是内存指针
- 内存指针指向了进程虚拟地址空间
- 通过页表结构和物理内存映射,程序在运行起来后,代码段里就运行着所写代码;
- 如果让该程序替换成另一个程序,就需要代码中调用进程替换函数;
- 当前运行的程序会更新代码段和数据段,并且更新堆栈;
- 所以当前的进程就运行其它程序,或者说是新程序
注意:
- 进程程序替换完后,进程就在指向新程序,但进程号不变,意味着当前进程不是新的进程;
- 但当前进程在执行新的程序
在代码中如何进行替换,就需要了解exec函数簇
exec函数簇
execl:
例:
ls -al
替换ls
:
- 第一个user bin是可执行程序本身,
第二个user bin是路径,
-al是命令行参数,
…是可变参数列表- 注:第一个参数必须是可执行程序本身;
NULL:命令行参数结束的标志
运行情况:- 屏幕先输出“准备替换”,然后还输出了当前路径下的文件信息,没有输出“替换失败”
原因:
- 程序替换成功后,就会运行新进程的代码,不会运行原进程代码
- 新进程的代码是展示当前路径下所有文件的信息;
- “替换失败”这个printf语句是原进程中的,
execl函数能打印出返回值,就表示替换失败
execlp:
p代表path,只在path中找
另一个例子:execlp(“pwd”, “pwd”, NULL);
第一个ls供系统去找执行谁
第二个ls是想怎样执行的
execle:
给程序传入对应的环境变量信息
执行自己的程序,或者其它语言写的程序
第一个参数指定路径,可以用绝对路径,也可以是相对路径
myexec是原程序,mycmd是待进行替换的程序
第三个参数是一个字符指针数组
myexec程序使用execle函数,将上述自定义的环境变量作为execle函数的第三个参数后,myexec连path都打印不出来了
如果不想覆盖,那么需要把新环境变量传给待替换的进程
- 先在bash处导入环境变量
- 将原程序中的execle函数的第三个参数设置为environ
有个环境变量是PATH
有环境变量:
想传入自定义的环境变量给待替换的程序
规律:
- 函数名带l:当前函数是一个可变参数列表的函数
- 函数名带p:当前函数会自动搜索环境变量
- 函数名带e:程序员需要自己组织环境变量
- 函数名带v:传递给待要替换的可执行程序行参数的组织格式为指针数组,注意的点与可变参数两点相同
- 以上函数都带有l,函数名中没有l表示当前函数的参数,不是可变参数列表的形式
execve:系统调用函数
execvp:
在替换的程序都是系统指令程序时,每次都要设置程序的路径
针对这种运行的都是系统指令程序的场景,大佬们就针对execve封装了一个新函数,第一个参数不用指定路径,默认会在PATH环境变量指定的路径下找
这个函数中也有个特殊的,环境变量默认使用当前进程已经有的环境变量,不用手动设置环境变量
execv:
每次替换程序的时候,环境变量多数情况没有什么好设置的,直接使用已经有的就行
execl和execv只有传参方式的区别
l:list
v:vector
execve是系统调用函数,其余5个函数都是库函数
进程替换场景
1.bash的应用场景:
之所以我们能在命令行执行各种命令(例如ls),本质上是我们和bash命令行解释器进行交互;
过程:
- 当我们在命令行输入了一个可执行程序后,这个程序就成为了bash代码块中的一部分,然后bash再去创建一个子进程,
- 该子进程是拷贝了父进程的PCB,子进程中的代码也是bash中的代码,最终的结果是运行我们写的可执行程序
这里面就用到了让子进程进行程序替换的技术
2.守护进程:一个产品是要一直为用户提供服务的,这个产品代码不能百分百不崩溃;
这里面就用到了守护进程:保护业务进程
怎样保护
- 启动业务进程时,不是启动业务程序,而是启动守护进程;
- 守护进程创建一个子进程,让子进程进行进程程序替换,成为业务程序进程;
- 替换完后守护进程创建出来的子进程就相当于业务进程,正常为用户服务;
- 守护进程和业务进程(子进程)进行进程通信(守护进程会循环判断业务进程的状态),让守护进程得知业务进程的情况:
- 业务进程正常:则守护进程不做处理;
- 业务进程崩溃或异常:则守护进程重新启动一个子进程,让子进程进行进程程序替换,和上述步骤一样
业务进程(子进程)会给内存返回一个时间,守护进程会读取并保存,下一次守护进程拿到的时间不变,则说明业务进程程序崩溃或异常