【进程控制】进程程序替换的原理以及exec函数族

简介: 【进程控制】进程程序替换的原理以及exec函数族

替换原理

在Linux中,进程的程序替换(Process Program Replacement)是指一个正在运行的进程使用exec函数族系统调用来加载并执行另一个程序的过程。这个新程序将替换掉原先正在执行的程序,成为该进程的新执行体,且会继承原先进程的一些属性,比如进程PID等。注意exec表示的是一个函数族,linux并没有这个函数,一共有 6 个:

进程=PCB+代码段+数据段

进程替换就是PCB信息基本保持不变,代码段和数据段被新程序替换。包括PID和PPID,在我们看来,程序被替换后可能执行完全不同的程序,这是我们程序员能直接感受到的。但是对于操作系统来说,它只认PID。只要PID没有变,那么就认为这个进程还是原来的进程。

这样做的好处是,可以在不创建新进程的情况下,动态地改变一个进程的执行代码和环境,从而实现程序的动态加载和替换。

可以理解为夺舍

我们常用子进程去执行另一个完全不同于父进程的程序。例如我们的bash进程执行命令。本来作为bash的子进程,代码和数据都是基本一致的,但是根据实际需求,子进程需要执行指令,也就需要将指令程序替换进来。

观察以下发生程序替换的例子:

exec函数族

有七种以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 execvpe(const char *file, char *const argv[],char *const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);

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

以上函数功能相似,在不用的场景下选择合适的函数。

解释函数名

exec函数族中函数带 p(比如execlp、execvp)的表示会自动搜索环境变量PATH.类似的函数名出现以下字符都表示特定的意义:

l(list):表示参数采用列表。

v(vector):表示参数用数组。

e(env) : 表示自己维护环境变量

解释参数

path表示的是可执行文件的路径

arg表示命令行参数的某个元素。第一个必须是程序名,其余每一个arg参数表示一条选项用逗号隔开。最后以NULL结尾(具体用法看上面例子)。

file表示可执行文件名,在execvp、execlp中会在其环境变量中去找。

enp[]表示环境变量数组,可提供给替换程序作为环境变量

argv[]表示命令行参数数组,以命令名为首,以NULL结尾。给替换程序提供命令选项。

事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节(系统调用),其它函数在man手册第3节(库函数)。

这些函数之间的关系如下图所示:

相关文章
|
7月前
|
Shell Linux C语言
函数和进程之间的相似性
在一个C程序可以fork/exec另一个程序,其过程是先fork一个子进程,然后让子进程使用exec系列函数将子进程的代码和数据替换为另一个程序的代码和数据,之后子进程就用该程序的数据执行该程序的代码,从而达到程序之间相互调用的效果。在学了C语言、C++或是JAVA等高级语言,你会知道,在这些语言中的函数是可以相互进行见调用的,但是在学习了Linux的前面的知识后,你就会有意无意的认识到其实进程也是与函数有相同之处的,进程之间也是可以相互调用的。程序之间相互调用带来的好处之一。那么下面就将这部分内容扩展。
121 0
|
网络协议 Linux
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
1602 2
|
Linux Python
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
586 2
|
Java Linux 调度
硬核揭秘:线程与进程的底层原理,面试高分必备!
嘿,大家好!我是小米,29岁的技术爱好者。今天来聊聊线程和进程的区别。进程是操作系统中运行的程序实例,有独立内存空间;线程是进程内的最小执行单元,共享内存。创建进程开销大但更安全,线程轻量高效但易引发数据竞争。面试时可强调:进程是资源分配单位,线程是CPU调度单位。根据不同场景选择合适的并发模型,如高并发用线程池。希望这篇文章能帮你更好地理解并回答面试中的相关问题,祝你早日拿下心仪的offer!
326 6
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
580 13
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
算法 调度 UED
操作系统中的进程管理:原理与实践
在数字世界的心脏跳动着无数进程,它们如同细胞一般构成了操作系统的生命体。本文将深入探讨进程管理的奥秘,从进程的诞生到成长,再到最终的消亡,揭示操作系统如何协调这些看似杂乱无章却又井然有序的活动。通过浅显易懂的语言和直观的比喻,我们将一起探索进程调度的策略、同步机制的重要性以及死锁问题的解决之道。准备好跟随我们的脚步,一起走进操作系统的微观世界,解锁进程管理的秘密吧!
240 6
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【9月更文挑战第13天】在编程的世界中,进程间通信(IPC)如同一场精彩的社交舞会,每个进程通过优雅的IPC机制交换信息,协同工作。本文将带你探索Python中的IPC奥秘,了解它是如何让程序实现无缝信息交流的。IPC如同隐形桥梁,连接各进程,使其跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存及套接字,适用于不同场景。通过一个简单的队列示例,我们将展示如何使用`multiprocessing.Queue`实现进程间通信,使程序如同社交达人般高效互动。掌握IPC,让你的程序在编程舞台上大放异彩。
164 3
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
684 0
|
编译器
【收藏】内核级利用通用Hook函数方法检测进程
【收藏】内核级利用通用Hook函数方法检测进程