在 Linux 系统中,进程程序替换是指一个正在运行的进程将其当前执行的程序完全替换为另一个程序的过程。这是通过 exec系列函数实现的,它们允许进程加载并运行不同的可执行文件。
基本概念
进程程序替换的特点:
- 替换后,进程ID保持不变
- 原进程的代码段、数据段和堆栈被新程序替换
替换原理
fork() 之后,父子各自执行父进程代码的一部分如果子进程就想执行一个全新的程序呢?进程的程序替换来完成这个功能!
程序替换是通过特定的接口,加载磁盘上的一个全新的程序(代码和数据),加载到调用进程的地址空间中!
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
替换函数
有六种以exec开头的函数,统称exec函数:它们功能相同但参数形式不同
函数解释
• 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
• 如果调用出错则返回-1
• 所以exec函数只有出错的返回值而没有成功的返回值。
命名理解
这些函数原型看起来很容易混,但只要掌握了规律就很好记。
• l(list) : 表示参数采用列表
• v(vector) : 参数用数组
• p(path) : 有p自动搜索环境变量PATH
• e(env) : 表示自己维护环境变量
函数实践
exec调用举例如下:
#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);
execv("/bin/ps", argv);
// 带p的,可以使用环境变量PATH,无需写全路径
execvp("ps", argv);
// 带e的,需要自己组装环境变量
execvpe("ps", argv, envp);
exit(0);
}
代码实践
这两个函数和上面两个函数的区别是需要定义一个数组,把命令放数组中,注意,数组中最后一个元素是NULL
我们在深入了解一下execv函数
子进程能够执行系统的命令,可以执行我自己的命令吗?当然可以,只要能找到
我们既可以自定义环境变量,也可以传递系统默认的环境变量
我们也可以同时传递自定义环境变量和系统默认的环境变量
事实上,只有execve是真正的系统调用,其它六个函数最终都调用execve,所以execve在man手册 第2节,其它函数在man手册第3节。
到此,进程控制之进程程序替换就讲完了,怎么样,是不是感觉大脑里面多了很多新知识。
如果觉得博主讲的还可以的话,就请大家多多支持博主,收藏加关注,追更不迷路
如果觉得博主哪里讲的不到位或是有疏漏,还请大家多多指出,博主一定会加以改正
博语小屋将持续为您推出文章