初识Linux · 进程替换

news/2024/10/3 23:33:23 标签: linux, 运维, 服务器

目录

前言:

1 直接看代码和现象

2 解释原理

3 将代码改成多进程版本

4 认识所有函数并使用


前言:

由前面的章节学习,我们已经了解了进程状态,进程终止以及进程等待,今天,我们学习进程替换。进程替换我们从如下几个点开始介绍,第一,直接看现象,第二,解释原理,第三,将代码改成多线程版本,第四,使用所有的替换函数,认识参数的含义。

废话不多说,直接进入主题。


1 直接看代码和现象

我们使用一段代码进入到进程替换:

int main()
{
	printf("test begin...\n");	
	execl("/usr/bin/ls","-l",NULL);
	printf("test end...\n");	
	return 0;
}

根据现象,我们可以看到,第二个printf是没有被执行的,但是第一个被执行了,而我们使用到的函数,叫做进程替换函数,它一共有6种,本质上我们理解了其中的2 - 3个,我们就会使用全部的了。我们不妨使用man手册查看一下:

输入:

man exec

从文档里面我们可以看到进程替换的函数版本有这么多个,每个函数都有返回值,但是呢我们不必在意返回值,因为通过现象,我们看到了执行进程替换函数之后的代码都失效了,所以返回值即使接受了,也没有用处。 

关心的情况只有一种,就是进程替换失败,但是这种情况十分的少见,我们就自然而然的给忽略了。


2 解释原理

首先我们要清楚一个问题,进程替换的全名不是进程替换,替换的不是进程,是程序,所以在进程程序替换的这个过程,本质上是没有创建新的进程的。

第一个点:进程程序替换中是没有创建新进程的,无非是程序替换了PCB里面原来的数据。这里我们不妨设想一个点,如果PCB里面是自己替换自己的多没意思,如果.cpp文件里的PCB可以被Java替换,shell脚本替换,岂不美哉?

第二个点,exec函数的作用是什么?

exec函数本质是一个加载函数,因为有了exec函数,在Linux中就可以将程序加载进去,因为进程程序替换的本质就是将不同的程序加载到内存里面,加载靠的就是exec*函数。


3 将代码改成多进程版本

将代码改成多线程版本,我们要做的事就是,父进程创建子进程,创建了之后,子进程执行被替换的程序,父进程只需要等待多个子进程就可以了。

此时,子进程的作用就有了两个,一个是执行父进程的代码部分,一个是让子进程执行一个全新的程序。

int main()
{
    printf("testexec ... begin!\n");
    pid_t id = fork();
    if (id == 0)
    {
        printf("child pid: %d\n", getpid());
        //child
        execl("/usr/bin/ls", "ls", "-l", NULL);
        exit(1);
    }
    int status = 0;
    pid_t rid = waitpid(id, &status, 0);
    if (rid > 0)
    {
        printf("father wait success, child exit code: %d\n", WEXITSTATUS(status));
    }
    printf("testexec ... end!\n");
    return 0;
}

该程序创建了一个子进程,子进程实现execl,如果执行失败,也就是替换失败,就走exit,程序直接退出,退出码为1,此时父进程只需要等待即可:

以上是现象,今天的重点都不是前三个,直接进入第四个。


4 认识所有函数并使用

所有的函数一共有execl execlp execle execv execvp execvpe,不难发现,拿命令行参数进行举例的话,选项一共有l p e v。

由参数,我们可以看到有pathname 和file,我们第一个使用的pathname即路径名,我们要从哪里执行程序,得通过该路径告诉它,file同理,就是文件名,那么对于execl,代表的就是列表,也就是在命令行中我们如何执行,在该函数里面就怎么书写即可。

拿这个举例:

execl("/usr/bin/ls","ls"."-l",NULL);

因为有l,所以我们要将平常执行ls命令的时候,如何执行的给列出来,这个参数不是固定,所以我们可以执行很多,ls -l -a -n都是可以的,但是注意点是最后的参数一定要是NULL,代表结束。

第二个函数:

execv,这里面的v代表的是vector,C++中的顺序表,所以我们看execv的参数是[],也就是我们应该这样干:

int main()
{
    char* const argv[] =
    {
        (char*)"ls",
        (char*)"-l",
        (char*)"-a",
        (char*)"--color",
        NULL
    };
    execv("/usr/bin/ls", argv);

    return 0;
}

但是注意点是,最后结尾的仍然要是NULL,这里的强转char*不是很必要,看自己的版本是否会进行报错吧。

对于execvp:

p代表的是PATH,也就是环境变量,用户可以不用传对应的路径,但是要传对应的文件,就像:

int main()
{
    char* const argv[] =
    {
        (char*)"ls",
        (char*)"-l",
        (char*)"-a",
        (char*)"--color",
        NULL
    };
    //execv("/usr/bin/ls", argv);
    execvp("ls",argv);
    return 0;
}

那么现在关于execlp就应该不用介绍了吧?l,list出来命令行怎么写的即可,p我们传对应的文件名即可。

现在还没介绍的就只有e了,e多好理解,environment,环境变量嘛不就是,当然了,因为父进程本身就有环境变量,子进程哪里用得着担心我没有环境变量啥的,根本不担心:

使用这里就不介绍了,同理即可。

本文是非常粗略的介绍了一下进程程序替换,很多细节没有介绍到,博主会在后面全部重新翻新的!!


感谢阅读!


http://www.niftyadmin.cn/n/5689120.html

相关文章

单调队列应用介绍

单调队列应用介绍 定义应用场景实现模板具体示例滑动窗口最大值问题描述问题分析代码实现带限制的子序列和问题描述问题分析代码实现跳跃游戏问题描述问题分析代码实现定义 队列(Queue)是另一种操作受限的线性表,只允许元素从队列的一端进,另一端出,具有先进先出(FIFO)的特…

大数据毕业设计选题推荐-民族服饰数据分析系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【rCore OS 开源操作系统】Rust 练习题题解: Enums

【rCore OS 开源操作系统】Rust 练习题题解: Enums 摘要 rCore OS 开源操作系统训练营学习中的代码练习部分。 在此记录下自己学习过程中的产物,以便于日后更有“收获感”。 后续还会继续完成其他章节的练习题题解。 正文 enums1 题目 // enums1.rs // // No hi…

Leetcode 275. H 指数 II

1.题目基本信息 1.1.题目描述 给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数,citations 已经按照 升序排列 。计算并返回该研究者的 h 指数。 h 指数的定义:h 代表“高引用次数”(high …

MySQL基础篇 - 事务

01 事务的简介 【1】什么是事务:事务是一组操作集合,要么同时操作成功,要么同时操作失败。 【2】对于MySQL数据库来说默认一条SQL语句就是一个事务,且事务是默认自动提交的。 我们可以把多条SQL语句设置成一个事务,使…

微软准备了 Windows 11 24H2 ISO “OOBE/BypassNRO“命令依然可用

Windows 11 24H2 可能在未来几周内开始推出。 微软已经要求 OEM 遵循新的指南准备好 Windows 11 24H2 就绪的驱动程序,并且现在已经开始准备媒体文件 (.ISO)。 OEM ISO 的链接已在微软服务器上发布。 一个标有"X23-81971_26100.1742.240906-0331.ge_release_sv…

overleaf的使用[11]:使用和管理LaTeX模板

菜鸟:嗨,老鸟,我最近在使用Overleaf写论文,但总觉得每次都要从头开始,效率好低。你能告诉我有什么办法可以改善这个情况吗? 老鸟:当然可以,菜鸟!你有没有听说过在Overle…

CentOS 7 系统中安装与配置 Telnet 服务详解(使用root登录)

目录 前言1. 安装 Telnet 服务端2. 配置 Telnet 服务允许 root 用户登录3. 启动与管理 Telnet 服务4. 配置防火墙允许 Telnet 通信5. 注册 Telnet 服务6. 添加 pts/0 终端7. 重启 xinetd 服务8. 在 Windows 本地终端安装 Telnet 客户端结语 前言 Telnet 是一种网络协议&#x…