Linux——进程控制2|进程程序替换|替换原理|替换函数|替换函数创建子进程|其余替换函数介绍|使用替换致函执行其它文件程序|使用替换致函执行其它语言文件|execlp |上

简介: 笔记

进程程序替换


替换原理

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


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


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

1.png



程序替换就是通过特定的接口,加载磁盘上的一个全新的程序(数据和代码)。加载到调用进程的上下文中(地址空间中),重新改一下页表和物理内存的关系就行,进程替换并没有创建新的子进程

2.png



替换函数

其实有六种以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 execve(const char *path, char *const argv[], char *const envp[]);

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


path:路径+目标文件名


…:可变参数列表


函数里可传入多个参数,最后一个参数,必须是NULL,表示参数传递完毕


演示:


注意这里ls的路径


这段程序正常运行


3.png4.png

加上execl,注意第一个参数和最后一个参数之间的参数,是我们在命令行上如何使用,就在这里如何书写

5.png6.png

在调用excel之后打印出来的内容跟直接调用ls一模一样

7.png8.png


execl运行成功以后,原程序的内容便不再执行,我们原始代码里还有一个printf没打印出来


execl是程序替换,调用该函数成功之后,会将当前进程的所有代码和数据进行替换,包括已经执行的和没执行的


所以,一旦调用成功,后续所有代码都不会再执行


故意写一个错代码

0.png

execl调用失败9.png

execl函数出错的时候才有返回值,返回值是-1,成功时没有返回值

10.png

我们一般这样写,如果执行了exit,则一定调用失败了


替换函数创建子进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
        pid_t id = fork();
        if(id == 0)
        {
           //子进程
            printf("子进程开始运行, pid: %d\n", getpid());
            execl("/usr/bin/ls","ls","-a","-l",NULL);
            sleep(3);
        }
        else 
        {
            //父进程
            printf("父进程开始运行, pid: %d\n", getpid());
            int status = 0;
            pid_t id = waitpid(-1, &status, 0); //阻塞等待, 一定是子进程先运行完毕,然后父进程获取之后,才退出!
            if(id > 0)
            {
                printf("wait success, exit code: %d\n", WEXITSTATUS(status));
            }
        }
    return 0;
}


11.png

阻塞等待, 一定是子进程先运行完毕,然后父进程获取之后,才退出!


创建子进程原因:如果不创建,替换的就是父进程,如果创建了,替换子进程,就不会影响父进程。


当子进程加载新程序,子进程和父进程代码会分离,也就是子进程会写时拷贝


其余替换函数介绍

exec系列函数的功能其实iu是加载器的底层接口


int execv(const char *path,char *const argv[])

path:文件路径+文件名


argv:指针数组,最后要以NULL结尾


execv中的v可看作vector方便记忆。

12.png13.png14.png

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

file:文件名(要执行谁),execlp,p代表会在path环境中查找


arg:命令行模式下使用格式,命令行参数必须以NULL结尾

15.png16.png

int execvp(const char *file,char *const argv[]);

file:文件名(你要执行谁)


argv:指针数组


17.png18.png

还有execv系列

19.png



函数名带


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

v(vector) : 参数用数组

p(path) : 有p自动搜索环境变量PATH

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

20.png

系统直接调用的是execve,上面的这些函数最终调用的都是excve这个接口,

21.png

相关文章
|
1天前
|
存储 算法 Linux
【Linux】文件打包解压_tar_zip
【Linux】文件打包解压_tar_zip
14 0
【Linux】文件打包解压_tar_zip
|
1天前
|
Linux 开发者
【Linux】:文件查看 stat、cat、more、less、head、tail、uniq、wc
【Linux】:文件查看 stat、cat、more、less、head、tail、uniq、wc
9 1
|
1天前
|
弹性计算 运维 Shell
统计Linux 进程相关数量信息
【4月更文挑战第29天】
5 0
|
1天前
|
弹性计算 运维 Shell
统计 Linux 进程相关数量信息
【4月更文挑战第29天】
6 1
|
2天前
|
Linux Python
【专栏】Linux 中某个目录中的文件数如何查看?这篇教程分分钟教会你!
【4月更文挑战第28天】在Linux中查看目录文件数的方法包括:使用`ls`结合`wc -l`,如`ls &lt;directory_path&gt; | wc -l`;使用`find`命令,如`find &lt;directory_path&gt; -type f | wc -l`;使用`tree`命令,如`tree &lt;directory_path&gt;`(可能需额外安装);以及通过编程方式,例如Python代码实现。注意权限、效率和选择适用方法以提升操作效率。本文提供了详细步骤和示例,助你轻松掌握!
|
2天前
|
监控 Linux Perl
【专栏】Linux 命令小技巧:显示文件指定行的内容
【4月更文挑战第28天】本文介绍了Linux中显示文件指定行内容的方法,包括使用`head`和`tail`命令显示文件头尾部分,利用`sed`的行号指定功能以及`awk`处理文本数据。文章还列举了在代码审查、日志分析和文本处理中的应用场景,并提醒注意文件编码、行号准确性及命令组合使用。通过练习和实践,可以提升Linux文本文件处理的效率。
|
2天前
|
存储 数据挖掘 Linux
【专栏】教你如何快速在 Linux 中找到某个目录中最大的文件
【4月更文挑战第28天】在 Linux 中查找目录中最大文件的方法包括:使用 `du` 结合 `sort`,`find` 结合 `xargs` 和 `sort`,以及编写 Python 脚本。这些技巧适用于服务器管理、数据分析和文件清理等场景,能帮助用户快速定位大文件进行分析、清理或优化。注意文件权限、目录深度和文件系统类型可能影响结果,可结合其他命令增强功能。
|
2天前
|
Linux 开发工具
【专栏】Linux 必备技能:如何在 Vim 中跳到文件的开头或者结尾?
【4月更文挑战第28天】本文介绍了Vim文本编辑器中快速跳转到文件开头和结尾的方法。使用`gg`或`1G`可跳转到文件开头,`G`或`$`则用于跳转到结尾。此外,还提到了跳转到指定行(如`10G`)和查找特定字符(如`f`+字符)的技巧,以提升编辑效率。
|
7天前
|
NoSQL Linux 程序员
【linux进程信号(一)】信号的概念以及产生信号的方式
【linux进程信号(一)】信号的概念以及产生信号的方式
|
7天前
|
Java Shell Linux
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?