欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 进程替换详解(Linux)

进程替换详解(Linux)

2025/2/12 12:21:28 来源:https://blog.csdn.net/kk6kk/article/details/145573396  浏览:    关键词:进程替换详解(Linux)

目录

1、先看代码 && 现象

2、解释原理

3、进程替换的作用

4、使用所有的替换方法,并且认识函数参数的含义


1、先看代码 && 现象

代码:

#include <stdio.h>
#include <unistd.h>int main()
{printf("testexec ... begin!\n");execl("/usr/bin/ls","ls","-l","-a",NULL);printf("testexec ... end!\n");return 0;
}


现象:

2、解释原理

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。

调用exec系列的函数并不创建新进程,所以调用exec前后该进程的id并未改变。

本质:就是将当前程序的代码和数据进行替换。

补充:站在被替换的进程的角度:本质就是这个程序被加载到了内存中了!

补充一个问题:这个过程是怎么加载的呢?

答:OS直接调用 exec* 系列的函数,这类函数就是类似于一种 Linux 上的加载函数。

补充:exec* 系列的函数,执行完毕之后,后面的代码就都被替换了。

注:exec 系列的函数的返回值是可以不关心的,因为如果替换成功,则不会执行原本后面的代码,如果替换失败,就会执行原本后面的代码,所以只需要看原本后面的代码有没有被执行,就能判断是否替换成功了。

3、进程替换的作用

  1. 让子进程执行父进程代码的一部分
  2. 让子进程去执行一个全新的程序(用 exec* 系列的函数) -- 注:此时不仅是数据需要写时拷贝,连代码都需要进行写时拷贝。

进程替换:

4、使用所有的替换方法,并且认识函数参数的含义

替换函数

其实有六种以exec开头的函数,统称exec函数:

#include <unistd.h>

int execl(const char *path, const char *arg, ...);

拿 execl 做例子,来详解一下:

path:所要运行的程序的路径(找到它)。

后面的参数的传参方式:在命令行中,是怎么执行这些命令的,那就怎么传参。

ex:

execl("/usr/bin/ls","ls","-a","l",NULL); -- 注:语法要求必须以 NULL 结尾。

总结:第一个参数是在问你“你想执行谁?”,后面的参数是在问你“你想怎么执行它?”

int execlp(const char *file, const char *arg, ...);

补充:const char *file:用户可以不传要执行的文件的路径(但是文件名要传),就是直接告诉 exec* ,我要执行谁就行了。

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[]); -- 注:只有这个是真正的系统调用,其他 5 个都是用C语言封装了 execve 后的库函数。

进程替换函数:

补充一个问题:有一个系统调用 execve 就够用了,为什么还要有其他 5 个库函数?

答:为了支持不同的应用场景。

补充:函数解释

  1. 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
  2. 如果调用出错则返回-1。
  3. 所以exec函数只有出错的返回值而没有成功的返回值。

命名理解

这些函数原型看起来很容易混,但只要掌握了规律就很好记。

  • l(list) : 表示参数的传参方式采用列表。
  • v(vector) : 表示参数的传参方式采用数组。
  • p(path) : 表示系统会自动在环境变量 PATH 中查找这个你要执行的程序。
  • e(env) : 表示整体替换所有的环境变量。-- 注:1、可以用全新的环境变量(自定义)给子进程 2、用老的环境变量给子进程(比如environ) 3、将老的环境变量修改一部分再给子进程

补充:putenv ,该函数可用于往当前环境变量中添加新的环境变量(具体用法看 man 手册)。

注:程序替换也可以替换成我们自己写的程序。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com