Linux--进程控制(2)--进程的程序替换(夺舍)

这篇具有很好参考价值的文章主要介绍了Linux--进程控制(2)--进程的程序替换(夺舍)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

进程的程序替换

0.相关函数

1.先看现象

 2.解释原理

3.将代码改成多进程版

 4.使用其它的替换函数,并且认识函数参数的含义

5.其它


进程的程序替换


0.相关函数

 关于进程替换我们需要了解的6个函数:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

函数解释:

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

命名理解:

  • l(list) : 表示参数采用列表
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

exec调用举例如下:

int main()
{
	char* const argv[] = { "ps", "-ef", NULL };
	char* const envp[] = { "PATH=/bin:/usr/bin", "TERM=console", NULL };
	execl("/bin/ps", "ps", "-ef", NULL);
	// 带p的,可以使用环境变量PATH,无需写全路径
	execlp("ps", "ps", "-ef", NULL);
	// 带e的,需要自己组装环境变量
	execle("ps", "ps", "-ef", NULL, envp);
	execv("/bin/ps", argv);
	// 带p的,可以使用环境变量PATH,无需写全路径
	execvp("ps", argv);
	// 带e的,需要自己组装环境变量
	execve("/bin/ps", argv, envp);
	exit(0);
}

      

1.先看现象

先来看一段代码:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

运行结果:我们发现让程序使用exec*函数,可以执行起来新的程序

我们还发现,执行玩这条语句,后面的语句都不执行了

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器


 2.解释原理

我们都知道,我们的可执行程序运行起来就变成了进程。

创建进程=创建内核相关管理的数据结构(task_struct,mm_struct,页表)+代码和数据。

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

        内存管理的数据,如代码段、数据段和堆栈等,则包含了程序执行所需的数据和代码。

        当我们谈论进程替换时,实际上是指用一个新的程序来完全替代当前进程的内存映像,也就是替换掉原有的代码段、数据段和堆栈等内存管理的数据。而CPU执行的上下文,如程序计数器、寄存器和程序状态字等,则会被新的程序所继承。这样,新的程序就可以从它的入口点开始执行,就像它是一个全新的进程一样。(但他不是一个全新的程序,因为这个过程并没有创建新的进程,只是替换掉了原进程的数据和代码,依旧使用原来进task_struct,mm_struct,页表) 用老进程的壳子执行新的代码和数据。(可以理解成被夺舍了)

        exec*函数族就是用来实现这种进程替换的系统调用。这些函数会根据指定的文件名找到可执行的文件,并用它来替换当前进程的内容。换句话说,它们会在当前进程内部执行一个全新的可执行文件。

 当你调用一个exec*函数时,它会做以下几件事情:

  1. 查找并加载新的程序文件到内存。
  2. 清除当前进程的内存映像,包括代码段、数据段和堆栈等。
  3. 将新的程序的代码和数据加载到当前进程的内存空间中。
  4. 更新程序计数器,使其指向新程序的入口点。
  5. 开始执行新程序。       

        值得注意的是,exec*函数执行成功就不需要关心它的返回值了。这是因为调用进程的实体,包括代码段、数据段和堆栈等,都已被新的内容所取代,只留下进程ID等一些表面上的信息保持原样。所以,一旦exec*函数执行成功,当前进程就已经被新的程序所替代,原有的程序已经不再存在。(这就是为什么在上面执行那段代码的时候,程序最后没有执行printf("test .... end!\n");)

        总的来说,exec*函数族是Linux环境下实现进程替换的重要工具。它们通过替换当前进程的内存映像来执行新的程序,使得我们可以在一个进程中执行不同的程序,从而实现程序的切换和执行流程的改变。
 


3.将代码改成多进程版

        我想进行程序替换,但我不想影响我父进程本身,这时候我们就可以把代码改成多进程版本,让子进程去进行替换,父进程进行wait就行了。

代码示例:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

运行结果:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器


 4.使用其它的替换函数,并且认识函数参数的含义

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

path : 我们要执行程序,需要带路径(怎么找到程序,你得告诉我)(你想执行谁)

list列表:在命令中怎么执行,就这么传参(标准情况)(你想怎么执行)

int execv(const char *path, char *const argv[])
path :和上面的一样

argv:是一个指针数组,直接把参数传到数组里

用法:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

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

p:用户可以不传要执行的文件路径(但是要穿文件名),查找这个程序,系统会自动在环境变量PATH中进行查找。

用法:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

int execle(const char *path, const char *arg, ...,char *const envp[]);
int execvpe(const char *path, char *const argv[], char *const envp[]);

这里的e:表示环境变量(environment)

上面的程序替换,我们替换的都是系统命令,可不可以替换我们自己的程序呢?

这是我们在C语言程序调用C++程序的方式

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

我们在C++程序中写的

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

编译c和c++程序运行c程序:我们成功的替换了我们自己的程序

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

接着谈环境变量。接上面代码:这一次我们将环境变量给了execvpe函数

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

我们在c++程序中接收了,命令行参数表和环境变量表并将它们打印出来了:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

编译运行看一下效果:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器

结论:我们平时自己运行的程序,命令行参数和环境变量,是父进程通过将自己的环境变量表和命令行参数表通过,execvpe函数传递来的。而我的父进程本身就有一批环境变量!!从bash来。(我们是可以将bash的环境变量表直接传给子进程的,就不做演示了)。


5.其它

         事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。

下图exec函数族 一个完整的例子:

Linux--进程控制(2)--进程的程序替换(夺舍),Linux学习,linux,运维,服务器文章来源地址https://www.toymoban.com/news/detail-861872.html

到了这里,关于Linux--进程控制(2)--进程的程序替换(夺舍)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux之进程控制&&进程终止&&进程等待&&进程的程序替换&&替换函数&&实现简易shell

    1.1 fork的使用 我们可以使用man指令来查看一下 子进程会复制父进程的PCB,之间代码共享,数据独有,拥有各自的进程虚拟地址空间。 这里就有一个代码共享,并且子进程是拷贝了父进程的PCB,虽然他们各自拥有自己的进程虚拟地址空间,数据是拷贝过来的,通过页表映射到

    2024年04月17日
    浏览(58)
  • 【探索Linux】—— 强大的命令行工具 P.10(进程的控制——创建、终止、等待、程序替换)

    前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的一些知识,也学习了一些Linux的基本操作,也了解并学习了有关Linux开发工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代码也相信大家都掌握的不错,上一篇文章我们了解了关于进程的地址空间,今

    2024年02月08日
    浏览(54)
  • 【Linux进程控制】进程创建 | 进程终止 | 进程等待 | 进程替换

    【写在前面】 本文主要学习理解 fork 的返回值、写时拷贝的工作细节、为什么要存在写时拷贝;进程退出码、进程退出的场景及常见的退出方法、对比 man 2 _exit 和 man 3 exit;进程终止、操作系统怎么进行释放资源、池的概念;进程等待的价值、进程等待的方法 wait 和 waitpid

    2023年04月08日
    浏览(38)
  • 【Linux从入门到精通】进程的控制(进程替换)

      本篇文章会对进程替换进行讲解。希望本篇文章会对你有所帮助  文章目录 一、进程替换概念 二、进程替换函数 2、1 execl 2、2 execlp 2、3 execv 2、3 execle 2、4 execve 三、总结 🙋‍♂️ 作者:@Ggggggtm 🙋‍♂️ 👀 专栏:Linux从入门到精通  👀 💥 标题:进程控制💥  ❣

    2024年02月16日
    浏览(45)
  • 【Linux】Linux进程控制 --- 进程创建、终止、等待、替换、shell派生子进程的理解…

    柴犬: 你好啊,屏幕前的大帅哥or大美女,和我一起享受美好的今天叭😃😃😃 1. 在调用fork函数之后, 当执行的程序代码转移到内核中的fork代码后 ,内核需要分配 新的内存块 和 内核数据结构 给子进程, 内核数据结构包括PCB、mm_struct和页表,然后构建起映射关系 ,同时

    2024年01月16日
    浏览(58)
  • [Linux]进程控制详解!!(创建、终止、等待、替换)

            hello,大家好,这里是bang___bang_,在上两篇中我们讲解了进程的概念、状态和进程地址空间,本篇讲解进程的控制!!包含内容有进程创建、进程等待、进程替换、进程终止!! 附上前2篇文章链接: Linux——操作系统进程详解!!(建议收藏细品!!)_bang___ba

    2024年02月15日
    浏览(43)
  • Linux :进程的程序替换

    目录 一、什么是程序替换 1.1程序替换的原理 1.2更改为多进程版本 二、各种exe接口 2.2execlp  ​编辑 2.2execv 2.3execle、execve、execvpe 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种

    2024年04月10日
    浏览(35)
  • 【Linux】进程的程序替换

    目标:为了让子进程帮父进程执行特定的任务 具体做法:1. 让子进程执行父进程的一部分代码 红框中的代码实际上是父进程的代码,在没有执行fork之前代码就有了,在没有创建子进程之前,父进程的代码加载到内存了,子进程被创建出来是没有独立的代码,这个代码是父进

    2024年01月17日
    浏览(45)
  • 【Linux】—— 进程程序替换

    目录 序言 (一)替换原理 1、进程角度——见见猪跑  1️⃣ 认识 execl 函数 2、程序角度——看图理解 (二)替换函数 1、命名理解  2、函数理解 1️⃣execlp 2️⃣execv 3️⃣execvp 4️⃣execle 5️⃣execve 6️⃣execve (三)自制shell 总结 在前面的文章中,我已经详细的讲解了进程

    2024年02月12日
    浏览(63)
  • 【Linux】详解进程程序替换

             用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。 调用exec并不创建新

    2024年04月18日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包