【lesson16】进程控制之进程替换(1)

2023-12-16 16:04
文章标签 进程 控制 替换 lesson16

本文主要是介绍【lesson16】进程控制之进程替换(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 进程替换是什么?
  • 进程替换怎么用?
    • 不创建子进程时使用

进程替换是什么?

我们知道fork()之后,父子进程各自执行父进程的一部分代码,如果子进程就想执行一个全新的程序呢?

以前:父子代码共享,数据写时拷贝各自一份

如果子进程想要有自己的代码呢?
我们可以用进程的程序替换来完成以上功能。

程序替换:是通过特定的接口,找到磁盘上的一个权限程序(代码+数据),把它加载到调用进程的物理内存中。
原理:
在这里插入图片描述
所以想进行程序替换我们只要将新的磁盘上的程序加载到内存,并和当前的进程页表重新建立映射关系即可

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
在这里插入图片描述
所以进程替换没有创建新的进程,因为OS并没有为该程序创建新的task_struct,用的全部都是之前程序的task_struct。

进程替换怎么用?

不创建子进程时使用

函数介绍:
在这里插入图片描述
可变参数列表:可以传入不定个数个参数。

我们在命令行上怎么执行的在这里就一个一个怎么填。
例如:ls -a -l 就直接填入"ls",‘’-a’',“-l”。
代码演示:
首先要知道ls的路径
在这里插入图片描述

#include <stdio.h>      
#include <unistd.h>      int main()                                   
{                                            printf("当前进程的开始代码\n");            execl("/usr/bin/ls","ls",NULL);    printf("当前进程的结束代码\n");    return 0;                          
} 

运行结果对比
在这里插入图片描述

我们看到确实可以查出来
再多传几个查看一下

#include <stdio.h>      
#include <unistd.h>      int main()      
{      printf("当前进程的开始代码\n");      //execl("/usr/bin/ls","ls",NULL);      execl("/usr/bin/ls","ls","-a","-l",NULL);    printf("当前进程的结束代码\n");      return 0;              
}

运行结果:
在这里插入图片描述
系统自身运行结果:
在这里插入图片描述

这里大家肯会有个一行为什么最后要传一个NULL因为execl函数是可变参数列表,所以我们要传一个NULL来告知它参数已经传递完毕。

这里大家肯会有疑惑为什么系统使用ls时查出来的信息是带颜色的,而自己查出来时并没有。
其实是系统起了别名:
在这里插入图片描述我们知道多传递一个==–color=auto==参数列表即可

#include <stdio.h>    
#include <unistd.h>    int main()    
{    printf("当前进程的开始代码\n");    //execl("/usr/bin/ls","ls",NULL);    execl("/usr/bin/ls","ls","-a","-l","--color=auto",NULL);                                                                                                              printf("当前进程的结束代码\n");    return 0;    
}

在这里插入图片描述

这里我就有一个问题了,我们代码后面不是有printf吗?为什么没有打印呢?
在这里插入图片描述
因为execl是程序替换,调用该函数成之后,会将当前进程的所有代码和数据都进行替换,包括已经执行的代码和未执行的代码。
所以一旦调用成功execl,后续所有代码,全部不会执行!
测试一下如果调用失败,我们后续代码会执行吗?
我们传入一个根本不存在的执行试一下

#include <stdio.h>    
#include <unistd.h>    int main()    
{    printf("当前进程的开始代码\n");    //execl("/usr/bin/ls","ls",NULL);    execl("/usr/bin/lss","lss","-a","-l","--color=auto",NULL);    printf("当前进程的结束代码\n");    return 0;                                                                                                                                                             
}   

在这里插入图片描述
我们这里看到execl函数调用失败之后,确实后续代码成功的输出,并没有被替换。

**execl为什么调用成功了,为什么不用它的返回值呢?**因为根本就不需要,返回值毫无用处,execl调用成功是会把自己都替换掉。

#include <stdio.h>      
#include <unistd.h>                                                           
#include <stdlib.h>      int main()    
{    printf("当前进程的开始代码\n");    //execl("/usr/bin/ls","ls",NULL);    execl("/usr/bin/ls","ls","-a","-l","--color=auto",NULL);                                                                                                              exit(1);                                               printf("当前进程的结束代码\n");                        return 0;                                              
}

在这里插入图片描述
我们可以看到这里的退出码是0,而不是1.

这篇关于【lesson16】进程控制之进程替换(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/501063

相关文章

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

如何将Tomcat容器替换为Jetty容器

《如何将Tomcat容器替换为Jetty容器》:本文主要介绍如何将Tomcat容器替换为Jetty容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat容器替换为Jetty容器修改Maven依赖配置文件调整(可选)重新构建和运行总结Tomcat容器替

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

Linux进程终止的N种方式详解

《Linux进程终止的N种方式详解》进程终止是操作系统中,进程的一个重要阶段,他标志着进程生命周期的结束,下面小编为大家整理了一些常见的Linux进程终止方式,大家可以根据需求选择... 目录前言一、进程终止的概念二、进程终止的场景三、进程终止的实现3.1 程序退出码3.2 运行完毕结果正常3.3 运行完毕