Linux进程控制-3

时间:2023-04-02 07:44:00

本片作为进程控制的最后一篇博客,来讲述进程控制中的最后一模块:程序替换的内容。

目录

程序替换

1.内容

2.接口

2.1execve

2.2execv

2.3execvp

2.4execl

2.5execlp

2.6execle

程序替换

1.内容

在真正了解程序替换之前,我们首先来明确两个知识点:pcb的内容和创建子进程的作用。

前者我们在进程概念中详细阐述过,在此我们简要概述一下,pcb是运行中程序的描述,底层的实现上是一个结构体;

后者从进程的角度而言,创建一个进程的目的即是为了完成某项任务,创建子进程的作用亦然,也是为了完成某项任务,对于子进程而言,它运行的程序内容可能和父进程相同--分摊压力;也可能是为了运行另一个程序--if(ret == 0)。

但是当子进程运行新的程序时,会见新任务的代码同当前的代码糅杂在一起,导致程序内容繁多,难以模块化处理。

因此我们创建了新的方法来实现,即对于书写的新任务程序,让子进程的pcb来管理调度和执行,这便是程序替换的主要思想。

总而言之,程序替换即是:将一个pcb所描述的调度管理程序,替换成另一个程序。换而言之,我们将一个新程序加载到内存当中,然后修改当前pcb进程的页表映射信息,初始化地址空间,让该pcb来管理调度新程序。

在了解完程序替换的内容之后,接下来我们讲述程序替换操作,即一些和程序替换相关的系统调用接口。

2.接口

2.1execve

int execve(char *path, char *argv[], char *env[]);

execve接口的作用:是将path这个路径名称所指定的程序加载到内存中,然后让当前进程调度管理这个程序的运行。

对于程序的运行会存在运行参数和环境变量,正如main函数中的参数会记录函数的运行参数和环境变量的内容和个数。

所以execve中参数:argv用于设定该程序的运行参数;env用于设定该程序的环境变量。 

最后,exevec的返回值内容是:失败返回-1;成功无返回值内容(代表新程序的运行)。

Linux进程控制-3

进行一个简单的接口操作示范便如上图所示,其中对于运行参数和环境变量是随意设置的,不用关心。主要体会程序替换的逻辑和execve接口实现的效果。

2.2execv

值得注意的是,对于环境变量env的设置,其实没有很明显的必要性,很多时候我们只需要使用原有的环境变量便可,所以为了节省程序替换的事件,设计者们推出execv函数来实现程序替换。

int exevc(char *path, char *argc[]);

对于exevc函数,它并不关心环境变量的设置,它在进行程序替换的时候会直接使用已有的环境变量。

2.3execvp

无论是exevce接口还是execv函数,我们对于替换的程序都需要指明它的路径。这样的行为伴随着一个十分明显的问题:当我们需要对系统指令进行多次调用时,每次的路径指明就很耗费时间。

针对上述execve和execv所存在的一定局限性,于是execvp应运而生,execvp时设计者所封装的一个库函数。

int exevcp(char *file, char *argc[]);

exevcp中的第一个参数不用指明具体的路径,默认会在PATH环境变量指定的路径下进行寻找。

2.4execl

对于上述接口中每次调用时都需要设定一个参数字符指针数组,较为繁琐,尤其在参数较少的情况下,每次定义就十分赘余,所以设计出execl来对其进行优化。

int execl(char *path, …/* char *arg */);

其中形参…(C语言)代表不定参(后面是加入的注释),即参数的个数不定。这样在我们进行程序替换的时候,当参数较少我们只需要将参数挨个输入到execl函数中作为形参,即可保证程序替换的正常运行。

这样很好的避免了当参数较少时,程序替换中设计参数的字符指针数据的步骤。

2.5execlp

同样的,对于指定路径也存在优化,即execlp接口。

int execlp(char *file, …);

2.6execle

int execle(char *path, … ,char *env[]);

和需要指明环境变量的调用接口execle,同样对于程序参数为函数的不定参。