Linux进程地址空间——下篇

news2024/11/26 0:42:54

目录

一.深入了解进程地址空间:

单个进程与进程地址空间与物理内存之间的联系图:

多个进程与进程地址空间与物理内存之间的联系图:

二.为什么会存在进程地址空间呢?

        作用1:进程地址空间的存在,保证了其他进程无法直接访问内存空间,保护了内存中代码和数据的安全性。

        作用2:地址空间的存在,保证了进程与进程之间代码数据的解耦——写实拷贝。保证了进程间的独立性特性。

        说作用3之前,再整体概述一下进程运行后与进程地址空间与物理内存的流程:

                那么虚拟地址是如何产生的呢?

                再举个生活上的例子加深理解:

        作用3:通过虚拟地址空间来屏蔽底层内存申请的过程,从而达到进程和OS进行内存管理操作,进行进程调度和内存管理相互解耦的操作。

        作用4: 让进程能够以统一的视角看待进程对应的代码数据等各个区域,让编译器也能以统一的视角进行代码的编译。

        作用5:进程地址空间的连续化区域划分,可以降低异常越界访问的概率。


        之前,我讲述了有关进程地址空间的定义概念,通过列举的几个例子从各方面更加深刻的理解到了进程地址空间:( Linux进程地址空间——上篇_)

接下来让我们继续理解进程地址空间的重要性吧!

一.深入了解进程地址空间:

单个进程与进程地址空间与物理内存之间的联系图:

        当磁盘中的可执行程序被加载到内存后,程序变为了进程,进程有了自己的PCB进程控制块(struct task_struct结构体),有了自己独立的进程地址空间(struct mm_struct结构体),该进程中的代码和数据也会被加载到内存中,因为进程地址空间中存放的是代码中各个变量和函数的虚拟地址,物理内存中存放的是各个变量和函数的物理地址,意味着变量和函数同时拥有两套地址,那么我们可以推论出:虚拟地址和物理地址是相互映射的。

        既然是相互映射,就好比我们使用汉语字典,通过偏旁部首、拼音等找法可以查找到我们需要的那一个汉字的具体所在页的具体解释。所以页表就担当了此种重任!页表是用来连接物理地址和虚拟地址相互映射的一张表,使得CPU可以通过虚拟地址找到物理地址,从而找到进程所在内存中的代码和数据。

        

多个进程与进程地址空间与物理内存之间的联系图:

       每个进程都认为它自己是独占内存空间的,都认为自己有4GB的物理内存空间(其实是4GB的虚拟地址空间),每个进程并不知道还有和自己一样的存在——操作系统画的大饼!

 

 


二.为什么会存在进程地址空间呢?

        作用1:进程地址空间的存在,保证了其他进程无法直接访问内存空间,保护了内存中代码和数据的安全性。

        根据上图,假如没有进程地址空间的话, 进程1可以直接访问物理内存,进入进程1的代码和数据后,完成相应的操作,但这也会有危险性,进程1可能会访问到进程2的代码数据,万一进程1是个伪装好的病毒进程,能够直接访问内存的话就会窃取到其他进程的数据资源,给用户造成极大的损失。

         所以进程地址空间的存在就好比是物理内存空间的保安,你必须经过检验,合法了才能够访问物理内存。

        举个例子:抗战时期,上海等地的共产党员前辈们为了能够在敌特后方潜伏下来获取情报,专门为自己建立了一个虚假的身份,目的就是为了更好的做潜伏工作,防止敌人怀疑自己。平常情况下就利用表面身份(虚拟地址)进行伪装,等给同志传递情报的时候,他们就会通过各种口语暗号(页表映射)表明彼此双方的真实身份(物理地址),在某时某地进行相关事宜的见面。

        注:检验是页表的事情,页表可不仅仅是用来虚拟地址映射物理地址的,还有检验拦截的作用,对于不合法的进程访问会进行拦截,它就无法访问到内存。


作用2:地址空间的存在,保证了进程与进程之间代码数据的解耦——写实拷贝。保证了进程间的独立性特性。

 

 

代码底层设计图解: 

 

gloval作为全局变量,子进程在执行流中修改了全局变量的值,gloval变为了300,但是在父进程的执行流中仍然是gloval=100。

形成情况的主要原因就是:gloval作为全局变量是共享数据,当某个进程修改了被共享的数据时,操作系统会根据被修改的数据重新拷贝一份,重新给其开辟空间,供子进程修改,那么以后子进程访问到gloval就是在内存中新开辟拷贝下的数据地址了,而父进程访问到的仍是原gloval的数据地址不变!

        这就体现了进程的独立性,多个进程之间的运行是互不影响的。 

 

 

       任何一方进程想要更改被进程多方共享的数据时,os操作系统都会对该方进程进行数据拷贝,形成新的物理地址,并且更改页表映射,最后让该进程进行修改。这一操作称为写时拷贝。

        写实拷贝技术的原因:提高进程创建的效率,有可能多个进程只是读取共享的数据,并不改。 所以当执行到修改共享数据时,操作系统才会开辟新的内存物理地址,拷贝数据到该新物理地址中,供该进程修改。


说作用3之前,再整体概述一下进程运行后与进程地址空间与物理内存的流程:

        可执行程序想要被执行,就得从磁盘被加载到内存中成为进程才行。成为进程后,操作系统会根据进程生成其PCB进程控制块,CPU不会执行进程,它只执行进程的PCB,CPU拿到进程PCB后,开始处理该进程的代码和数据。在处理过程中,CPU获取到了代码中的各种函数和变量的虚拟地址,这是不够的,它得去内存中找代码形成的逻辑,找到执行指令才能用继续运行。于是CPU通过寻找PCB的参数指针指向虚拟地址空间,在代码区,数据区或者堆栈区找到这些函数和变量的虚拟地址,将这些虚拟地址再通过页表映射找到在内存的物理地址。于是CPU成功在内存中找到了这些函数,但CPU不认识物理地址,于是让操作系统携带着内存的指令传回CPU去执行。

那么虚拟地址是如何产生的呢?

        例:

        当我们的my.c文件经过编译的过程中,就会生成虚拟地址,比如全局变量a经过编译,有了0x2222的地址,fun,main函数也有了各自的虚拟地址 ! ! !

 

       

        cpu在运行该进程的PCB时,会执行进程里面的代码数据,例如用到变量a时,CPU会通过进程地址空间的虚拟地址,通过查找页表,映射到物理地址。在内存中,该变量a会将自己的虚拟地址再传回CPU中执行指令;当cpu用到main函数,fun函数时也是这样,cpu进入地址空间通过页表找到这些函数所在内存物理地址后,这些函数所涉及到的运算指令会进入CPU中执行相应的操作。

  注意: CPU执行的是指令,它只认识虚拟地址,通过虚拟地址去执行指令操作从始至终CPU都不会遇到这些函数的物理地址!

 

再举个生活上的例子加深理解:

       当我们高考完准备上大学的时候,收到了录取通知书,有了自己的学籍(录取通知书和学籍就是程序的信息描述),入学当天,我们就好比是可执行程序。入学前我们是磁盘中的可执行程序,入学后就好比是我们被加载到内存成为了进程。而我们的被分配到21号宿舍楼,x层X号宿舍,宿舍楼房间号就是内存(物理地址),而我们的学号就是虚拟地址。辅导员安排班长要求我们打扫教室的时候,说学号尾号为0-3的礼拜一打扫崇学楼,4-6的礼拜二打扫崇学楼....。                           

 注:男生宿舍楼离崇学楼远,女生离崇学楼近。


        老师不管我们的宿舍楼离教学楼是否远,只要求按照学号要求进行打扫。而老师就好比是CPU,不管我们住哪里(物理地址),不管离打扫的地方多远,只说学号0-3的,4-6(虚拟地址)的按指定的日期进行打扫。
        打扫完的学生按学号登记报表并报回给辅导员(报回就好比是内存中的代码将自己的虚拟地址传回到CPU一一步骤4)。若是有忘记打扫的,辅导员会让班长去通知,例如,小明忘记今天打扫了,班长拿着班名册信息表(页表) 去找宿舍楼xx宿舍号找小明,告知他及时去打扫。

 


作用3:通过虚拟地址空间来屏蔽底层内存申请的过程,从而达到进程和OS进行内存管理操作,进行进程调度和内存管理相互解耦的操作。

操作系统有四种核心管理:进程管理、内存管理、驱动管理、文件管理。

       如果没有进程地址空间,进程直接访问物理内存,当进程退出时,内存管理需要尽快将该进程回收,在这个过程当中必须得保证内存管理得知道某个进程的退出信号,内存管理也得知道某个进程开始的信号,这样操作系统才能给它们及时的分配资源和回收资源,这就意味着内存管理和进程管理模块是强耦合的。

        也就是说内存管理和进程管理联系比较大,通过我们上面的理解,如果有了进程地址空间,当一个进程需要资源的时候,通过页表映射去要就可以了,内存管理就只需要知道哪些内存区域(配置)是无效的,哪些是有效的(被页表映射的就是有效的,没有被页表映射的就是无效的),当一个进程退出时,它的映射关系也就没了,此时没有了映射关系,物理内存就将该进程的数据设置称无效的。

        所以第二个好处就是将内存管理和进程管理进行解耦,内存管理是怎么知道有效还是无效的呢? 比如说在-块物理内存区域设置一个计数器count,当页表中有映射到这块区域时,count就++,当一个映射去掉时,就将count--,内存管理只需要检测这个count是不是0,如果为0,说明它是没人用的。


作用4: 让进程能够以统一的视角看待进程对应的代码数据等各个区域,让编译器也能以统一的视角进行代码的编译。

作用5:进程地址空间的连续化区域划分,可以降低异常越界访问的概率。


 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/584618.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter 笔记 | Flutter 文件IO、网络请求、JSON、日期与国际化

文件IO操作 Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的,不过和 Dart VM 相比,Flutte…

6.1 进程的创建和回收

目录 进程概念 程序 进程 进程内容 进程控制块 进程类型 进程状态 常用命令 查看进程信息 进程相关命令 进程的创建和结束 子进程概念 子进程创建-fork 父子进程 进程结束-exit/_exit 进程结束-exit-示例1 进程结束-exit-示例2 进程回收 进程回收-wait 进程回…

企业数字化转型,为什么会加快商业智能BI的发展

对于企业数字化转型来说,数据是其中提到最多的词汇。当今世界,随着人们认识到数据的重要性,明白了数据发挥价值的方式及其意义,数据资产就成为数字化转型企业需要掌握利用的关键。 数据可视化 - 派可数据商业智能BI可视化分析平台…

服务windows服务+辅助角色服务

1、vs2022新建一个windows服务项目 2、修改服务参数 (1)AutoLog: 是否将事件写入到windows的事件日志中。 (2)canpauseandContinue:服务是否可以暂停和继续 3、添加服务安装程序 在界面内右击鼠标 新建一个服务、新建后如下图&a…

【运维】speedtest测试

目录 docker 布署 布署云端 docker布署 云端放置于已有容器里 librespeed/speedtest: Self-hosted Speedtest for HTML5 and more. Easy setup, examples, configurable, mobile friendly. Supports PHP, Node, Multiple servers, and more (github.com) docker 布署 获取…

探讨生产环境下缓存雪崩的几种场景及解决方案

本文首发自「慕课网」(www.imooc.com),想了解更多IT干货内容,程序员圈内热闻,欢迎关注"慕课网"或慕课网公众号! 作者:大能 | 慕课网讲师 缓存我们经常使用,但是有时候我们…

如何撤消 Git 中最新的本地提交?

在使用Git进行版本控制时,有时我们可能会犯下错误或者想要撤销最新的本地提交。Git提供了一些强大的工具和命令,使我们能够轻松地撤消最近的提交并修复错误。 本文将详细介绍如何在Git中撤消最新的本地提交。 步骤1:查看提交历史 在撤消最新…

Centos7安装Java8(在线安装避坑详细安装)

开篇语: 喜欢在一个明媚阳光的午后 坐在那夕阳斑驳的南墙下 听着风起 闻着花香 望着远山 身边是你 如此便觉得很好 1.查看目前环境 rpm -qa|grep jdk在这里我们会发现,原有系统安装有jdk,如果对于jdk有要求,我们就需要重新安装jdk…

Liunx网络基础(3)传输层(TCP/UDP)可靠传输、字节流传输等

传输层协议 传输层协议解析: 负责两端之间的数据传输; TCP/ UDP 1. UDP UDP: 用户数据报协议,无连接,不可靠,面向数据报传输 重点: 协议格式,协议特性,特性对于编程的影响 协议格式: 16位源端口 & 16位…

2023-05-29 用 fltk gui库编写一个打字练习程序

用 fltk gui库编写一个打字练习程序 前言一、FLTK GUI 库二、使用步骤1.引入库2.使用代码 总结 前言 给孩子练习键盘打字, 发现终端还是欠点意思, 研究了一下gui, 最终用 fltk库弄了一个. 对于没有接触过gui的人, 发现, 编程的逻辑和终端区别很大, 很繁琐, 可能需要适应适应,…

Windows远程Centos7图形化界面

一、centos7服务器安装tigervnc 1、更新yum源 yum update 2、安装tigervnc yum -y install tigervnc* 3、启动vnc vncserver (1)执行命令后需要输入密码 (2)再次输入密码 注意:密码一定要记住,方便以…

链表反转方法汇总

反转范围之前有节点,prev就指向该节点,没有就prevnull; 一、头插法 class Solution {public ListNode reverseList(ListNode head) {ListNode header new ListNode(-1);ListNode cur head;while(cur ! null) {ListNode tmp cur.next;cur.…

LabVIEWCompactRIO 开发指南第六章41 同步模块

同步模块 同时运行的模块每个通道有一个ADC,并且采集数据时通道之间没有明显的偏差。同步模块的两个子类别,按需和三角积分,通过SPI总线传输数据,并受到其他SPI总线模块的所有规格和挑战的约束。 按需转换 表6.1.具有按需转换的…

Postgresql源码(104)子连接提升过程pull_up_sublinks

1 场景构造 drop table student; create table student(sno int primary key, sname varchar(10), ssex int); insert into student values(1, stu1, 0); insert into student values(2, stu2, 1); insert into student values(3, stu3, 1); insert into student values(4, st…

模块化

一、目标 能够说出模块化的好处能够知道CommonJS规定了哪些内容能够说出Node.js中模块的三大分类各自是什么能够使用npm管理包能够了解什么是规范的包结构能够了解模块的加载机制 二、目录 模块化的基本概念Node.js中模块的分类npm与包模块的加载机制 1.模块化的基本概念 …

spring源码解读

深入了解Spring Bean Java bean和spring bean区别 Java bean的属性私有,只能通过get和set方法来对属性进行操作。Spring bean是由spring容器生成和管理的对象。 spring Bean的定义方式 xml文件 。 声明式。 bean注解。 声明式。 component注解。声明式。 Bea…

房产中介APP开发功能有哪些?

房产中介APP开发功能有哪些? 1. 发布信息。中介或房东通过房地产中介APP客户端发布出租房屋的相关信息。 2. 房屋搜查。根据不同类型的房源进行分类,如公寓、整租、合租、写字楼、办公楼等,也可以根据不同的位置信息、商圈、距…

2023年下半年软考高级需要报班吗?

首先,对于软考高级考试报班与否的问题,需要根据自身的情况来做出决定。如果你有较强的自学能力,且具备丰富的实际工作经验和技术知识,那么不报班也完全可以自学备考。但如果你对软件工程的知识掌握程度较低,或者时间紧…

算法01-算法概念与描述

文章目录 总结大纲要求算法概念举个例子:量水问题 算法描述算法的时间复杂度 总结 本系列为C算法学习系列,会介绍 算法概念与描述,入门算法,基础算法,数值处理算法,排序算法,搜索算法&#xff…

软件测试炸了,作为从业者,你做好准备了吗?

软件测试行业已经发生很大变化,你跟上变化了吗? 岗位少不可怕,要求越来越高也不可怕,可怕的是,软件测试行业已经发生巨变,而你却原地踏步!目前一线大厂更多倾向于招收测试开发,或者…