Linux初识地址空间

news2024/10/7 7:30:04

前言

上一期我们对进程优先级、命令行参数以及环境和变量做了介绍!以前我们就提到过一个问题有了运行队列为什么还要有优先级?本期将带你揭晓!

本期内容介绍

虚拟地址空间的引入

虚拟地址空间的介绍

如何理解地址空间

为什么要有地址空间

如何进一步理解页表和写时拷贝

解决历史遗留问题

虚拟地址空间

1.1虚拟地址空间的引入

OK,我们先来看看这样的一段代码:

这段代码是创建了父子进程,分别打印其pid、ppid以及一个全局变量的值和地址, 5秒后子进程把g_val给修改成了300;OK,我们来看看结果:

这里的结果是,前5秒父子进程都是打印的100,5秒后子进程把g_val修改了变成了300, 所以以后子进程的g_val就是300,而父进程的不变!这一点也可以理解,我们知道进程=task_struct(PCB)+其代码和数据;fork之后产生了子进程,而子进程的本质是在操作系统中多了一个进程即多了一套task_struct(PCB)+代码和数据,而以前介绍过子进程的代码是可以继承父进程的,如果子进程不对数据修改,子进程和父进程共享数据(注意:这里可没说子进程继承父进程的数据!!);这里子进程虽然修改了数据但父子进程具有独立性,所以父子进程数据也得想办法独立,可以理解的!但是让我们震惊的根本就不是这个,而是父子进程的g_val的地址是一样的!按照以往的理解就是一个变量既等于100又等于300,这怎么可能??所以我们可以得出一个结论:上面g_val的地址绝对是物理地址!!!,不是物理地址(物理内存的地址)那是啥呢?其实这是虚拟地址!!

1.2虚拟地址空间的介绍

虚拟地址空间我们是学习过的,在C语言、以及C++的时候都是介绍过的;就是下面这个:

不过当时在C语言和C++没有介绍是因为,这个东西本身就不是语言的问题,而是操作系统层面的知识!例如上面的例子,如果没有学系统,看到上面的代码后三观直接震碎!OK,言归正传,继续上回到虚拟地址空间上,以前我们介绍过:当一个进程在被调度时,会先把他的代码和数据加载到内存,然后操作系统会为其创建一个PCB(task_struct)来描述该进程的属性,并把PCB以某种数据结构组织起来,方便管理,即"先描述,在组织"!其实,当一个进程加载到内存时系统并不会只创建一个PCB,还会创建地址空间和页表来一起管理该进程!

我们以前所有程序的地址都是虚拟地址,并非物理地址!这里的虚拟地址就是你虚拟地址空间的地址,每个进程再被加载前都会为其分配一个虚拟地址空间!

页表是进行虚拟地址和物理地址转换的!

页表和虚拟地址空间本质也是和PCB一样的进程内核数据结构,所以系统也会对其进行管理的,如何管理?先描述,在组织!

如下图:

OK,和以前的一样不在多说~!所以,有了虚拟地址空间和页表的介绍,我们就可以理解上述的g_val父子进程的地址为什么是一样的了!

fork之后有了子进程,即有了子进程的代码和数据、PCB、虚拟地址空间、以及页表!其中代码、PCB(pid、ppid等除外)、虚拟地址空间、页表都是继承自父进程的;此时,父进程和子进程的地址空间的内容是一模一样的,所以他们指向的数据也是一样的,即此时数据形成浅拷贝!也就是我们前面所说的父子进程共享数据,而后面子进程对数据修改了,此时操作系统检测到了之后会对子进程的数据进行写实拷贝(OS自主完成的,用户感受不到),然后让子进程修改,所以子进程修改的是父进程数据的拷贝,所以子进程修改后父进程的g_val不变!这也符合我们介绍的,进程具有独立性!

如下图:

OK,理解了这里就可回答下面的问题了!

1、如果父子进程不对数据进行修改,是不是父子进程共享的呢?

是的,刚刚上面介绍了,父子进程如果不对数据进行修改,他们是都是共享一份数据的!

2、为什么要实行写实拷贝?可不可以在创建子进程时,把父进程的数据全部给子进程拷贝一份?

写实拷贝的本质是一种按需申请,通过拷贝的时间顺序达到有效节省空间的目的!

例如,进程的数据有环境变量、命令行参数等这些子进程几乎是不会修改的,如果你直接在创建子进程的时候拷贝一份话,会造成不必要的空间浪费!因为这些东西很少修改,父子进程共享即可,如果等到子进程真正的需要修改的时候给他开空间,写入即可!另一方面,即使子进程真的有内存需要,例如他在5秒后要一段malloc或new的空间,如果是一开始给子进程拷贝一份的话,前5秒他不用,这样一来是不是在5秒的时间内浪费了这一块空间?系统说不一定在这5秒内可以拿着这些空间做更多的事情,如果是写实拷贝的话,一开始只给页表一个虚拟地址,其对应的物理地址可以不给,等到真正用的时候再去申请即可!这样就提升了内存实时的使用效率!

1.3如何理解地址空间?

地址空间的本质就是内核的一个struct结构体!内部有很多的start和end,表示某个区域的范围!

我们举个例子就可以理解了:

假设你是一个上小学的文静的小男生或小女生,你的同桌是一个非常邋遢的同学,是不是把这放桌上,把那放桌上,你有一次受不了了,就在桌子上画了一条38线, 假设桌子长100cm,38线是在50cm处;左边属于你,右边的属于他!此时你对你们的桌子进行了区域划分,同理,你有一块内存空间,要分为很多的区,是不是也可以向上面的38线一样分区!

假设你同桌今天又把鞋子放到你桌边上了,你一起之下,把38线向右移动了20厘米直接73开:

所以这样就把区域划分变成了对每个对象的start和end的修改!其实内核中也是类似这样的,OK,来看看内核中的地址空间的区域划分:

1.4为什么要有地址空间?

要理解这个问题就先得理解好地址空间!OK,还是来一个例子:

在遥远的漂亮国有一个土豪,他有n个私生子,这些私生子相互不知道对方的存在!现在土豪先找到大儿子,说Tom最近老爹听说你在微软上班了?大儿子说嗯,土豪说可以不愧是我儿子,好好干老爹我现在身价100亿美金,等以后都是你的!大儿子一听好呀好呀~!然后土豪又找到二儿子,他二儿子在考博士,土豪说儿子听说你在考律师的博士?二儿子说是的老爹,土豪同样又说,好好学等你以后成功了,老爹的这100亿都是你的,二儿子也是很高兴的同意了~!过了几天这个土豪又找到他的私生女,说小爱呀听说你在做珠宝生意?小爱说是的呢,然后同样的套路给小爱说老爹现在又100亿你好好干以后都是你的~!小爱也点了头,然后又找到了它的小儿子说儿子听说你在准备申请上大学??小儿子点了点头,土豪又说,你只要能够申请到中国的清华大学老爹的这100亿都是你的.....

这里的土豪就是操作系统,这里的每个私生子就是每个进程,土豪给每个私生子(进程)画的大饼就是虚拟地址空间!

理解了这些现在再来谈一下为什么要有地址空间!主要有以下3个原因:

1、将无序变有序,让进程以统一的视角看待物理内存,以及自己运行的各个区域!

2、进程管理和内存管理进行解耦

3、拦截非法的请求(对物理内存的保护)

4、使每个进程保持独立性

什么意思呢?就是通过虚拟地址空间可以让每一个进程都以为自己的数据永远在某个地址处(虚拟地址)无需关心物理内存在哪里,其实它的真实的数据可能在物理内存的另一地址处!这样进程就变得更加好管理进程和内存了,这其实也是一种封装和C++STL迭代器类似,看似都一样,其实底层天差地别!这样每个进程都觉得每一个进程都是操作系统的唯一,而其实并不是~!关于拦截非法的请求,也是举个例子:比如说数组越界,其实是虚拟地址空间映射到页表时页表就已经检查出来了,这样就防止了对物理内存的随便乱访问,即保护了物理内存!

1.5如何进一步的理解页表和写实拷贝?

关于页表,我们这里只是非常简单的介绍了一下,什么多级页表都没提,这里只是先简单的见一下,后面动静态库以及多线程会在次介绍的!!这想说的意思是不要把页表像的过于简单了!OK,页表不光是对虚拟与物理地址的映射,还可以对非法的请求进行拦截即权限标志位的检查、是否在内存等!OK,再举个栗子:

char* str = "hello";
*str = 'H';

这段代码一执行就挂了,原因是给静态区的常量字符串赋值了!OK,语言层面是这样讲的,但是现在的问题是为什么不能够对静态区的常量赋值呢?其实是在赋值的时候再页表的时候被页表给拦截了!因为页表内部有一个标记位标记的是该地址处的数据是否有相应的权限,常量区的数据那必然只有写权限,你一写入页表就拦截了反馈给OS,操作系统就把你的进程给搞挂了~!

也就是,如果你的进程在进京某种操作时,都会经过页表的检查,如果合法让你操作物理内存,否则反馈给OS,OS会交给判断处理!例如,你的代码比如说由于内存压力大给把一部分挂起到磁盘了,当你进程在访问时页表一查虚拟地址存在但是物理地址不存在,此时发生错误,交给OS,OS检查完后发现是发生了缺页中断;再比如说在写入时发现要该数据被多个进程同时引用,此时反馈给OS,发现需要写实拷贝!如果上述都不是就需异常处理!

1.6历史遗留问题

我们在以前刚刚接触子进程的时候,这段代码:

当时看到一个变量的值即是大于0又是等于0,感觉三观直接崩塌了,其实现在介绍了虚拟地址空间后,现在再来看是很好理解的,fork后要return xxx;本质是对同一个变量id的写入,不管是谁先返回即写入就会发生写时拷贝,然后父子进程有了自己独立的物理内存的id而正在虚拟地址层面上他们的地址还是一样的!

OK,本期内容就介绍到这里,好兄弟,我们下期再见~!

结束语:我们不应该被眼前的一些所谓的华丽所迷惑,更应坚守初心,一步步的朝目标前进!

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

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

相关文章

这些话术怎么我准备面试的时候没有刷到过!

“金三银四"过半,打算趁此转岗、跳槽的你还顺利吗...... 最近收到很多关于面试的咨询,小伙伴表示找工作真的太难了, 一个比一个卷,甚至到了怀疑自己的地步:自己是不是不够优秀? 有时候不是自己不够优…

一文入门gcc

今天我们来玩玩gcc。 是因为突然发现ESP-IDF用的是CMake,要了解CMake最好就要先学习Makefile有个基础,学习Makefile最好就要先熟悉gcc,所以就有了今天这篇文章。 首先我们要明确一个问题,那就是gcc/g是什么,它们有什…

IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照(snapshot)JAR 包

IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照(snapshot)JAR 包 目录 IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照(snapshot)JAR 包1. 检查 settings.xml2. IDEA Maven 配置3. 强制更新 Snapshot4. 使用…

解锁5G新营销:视频短信的优势与全方位推广策略

随着5G时代的全面来临,企业的数字化转型步伐日益加快,视频短信作为新兴的数字营销工具,正逐步展现出其巨大的潜力。视频短信群发以其独特的形式和内容,将图片、文字、视频、声音融为一体,为用户带来全新的直观感受&…

6月17号直播预告 | 认识XPCIE1032H控制卡以及单轴PSO视觉飞拍和精准输出知识分享

在智能装备领域,精度、效率和产能是关键的竞争力指标,大多数都面临备货排产要求高、需要调度协同生产和更高的加工精度等问题,特别是在3C电子、半导体设备、锂电光伏等高速高精制造领域。 运动控制系统的性能直接影响生产质量和效率&#xf…

Vue54-浏览器的本地存储webStorage

一、本地存储localStorage的作用 二、本地存储的代码实现 2-1、存储数据 注意: localStorage是window上的函数,所以,可以把window.localStorage直接写成localStorage(直接调用!) 默认调了p.toString()方…

充电宝什么牌子耐用?2024年四大品牌推荐!这四款值得入!

在现代生活中,充电宝已经成为我们日常必备的数码配件之一。无论是旅行、出差还是日常通勤,拥有一款耐用且高效的充电宝,能够为我们的电子设备提供源源不断的电力支持。然而,市场上充电宝品牌众多,质量参差不齐&#xf…

Redis 7.x 系列【3】多种连接方式

有道无术,术尚可求,有术无道,止于术。 本系列Redis 版本 7.2.5 源码地址:https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. Redis Cli3. 可视化管理工具3.1 Redis Insight3.2 RedisDesktopManager 4. …

AI图书推荐:用ChatGPT按需DIY定制来赚钱

《用ChatGPT按需DIY定制来赚钱》ChatGPT Print Money Method ,作者是Cindy Donovan 。 下面是图书概要: ### 第一章:什么是按需印刷以及ChatGPT如何使其变得简单易行? 本章介绍了按需印刷的商业模式,即仅在收到订单时…

解析工业制氮机的应用特点

工业制氮机,作为现代工业生产中不可或缺的重要设备,以其独特的工作原理和广泛的应用领域,为众多行业提供了高效、便捷的氮气制取方案。本文将详细探讨工业制氮机的应用特点,以便更好地了解其在工业生产中的重要作用。 工业制氮机具…

「51媒体」媒体邀约如何高效沟通?

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 企业在做活动会议时,往往希望对活动信息或者公司品牌进行一个报道和曝光,那么如何有效且高效的完成与媒体的沟通呢?今天胡老师就来分享下这方面的一些…

【Spring】1. Maven项目管理

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…

centos7 离线安装zip和unzip

解压的时候发现不能解压,报-bash: unzip: command not found 1、访问https://www.rpmfind.net/linux/rpm2html/search.php?query=zip&submit=Search+…&system=centos&arch=#/ 2、输入zip和centos搜索,选择el7下载 3、输入unzip和centos搜索,选择el7下载: 安…

【LLM之RAG】RAT论文阅读笔记

研究背景 近年来,大型语言模型(LLMs)在各种自然语言推理任务上取得了显著进展,尤其是在结合大规模模型和复杂提示策略(如链式思维提示(CoT))时。然而,LLMs 在推理的事实…

小程序简单版音乐播放器

小程序简单版音乐播放器 结构 先来看看页面结构 <!-- wxml --><!-- 标签页标题 --> <view class"tab"><view class"tab-item {{tab0?active:}}" bindtap"changeItem" data-item"0">音乐推荐</view><…

DAY5-力扣刷题

1.两两交换链表中的节点 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换…

ElasticSearch + kibana:类型声明

当我们使用 kibana 创建索引时&#xff0c;如果不申明数据类型&#xff0c;默认字符串赋予 text类型&#xff0c;如下图所示 接下来我们继续创建多条数据如下&#xff1a; 下面我们来检索下&#xff1a; 通过以上两个案例我们发现&#xff0c;使用 match 模糊查询 li-3 明明…

亚马逊、速卖通等跨境平台测评自养号有哪些好处?

测评自养号顾名思义就是自己用国外真实环境养出来的买家账号&#xff0c;通过国外的手机号、邮箱、真实收货地址&#xff0c;设备环境、当地的住宅IP注册和养出来的买手号 很多卖家都了解过自养号&#xff0c;注册一个账号成本就几块钱&#xff0c;账号又可以长期使用&#xf…

【机器学习】图神经网络:深度解析图神经网络的基本构成和原理以及关键技术

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言一、图数据及其应用场景1.1 图数据的定义和特征1.2 常见的图数据结构1.2.1 社交网络1.2.2 知识图谱1.2.3 分子结构1.2.4 交通网络 1.3 图数据在不同领域的应用实例1.3.1 社交网络中的推荐系统1.3.2 知识图谱中的信息检索…

如何学习创建和使用 Java 归档(JAR)文件

1. 简介 JAR&#xff08;Java ARchive&#xff09;文件是一种用于打包多个Java类、资源文件和元数据的压缩文件格式。它在Java开发和发布过程中扮演着重要角色。通过使用JAR文件&#xff0c;开发者可以将应用程序的所有组件打包在一个文件中&#xff0c;方便分发和部署。 2. …