Linux进程【2】进程地址空间(+页表详解哦)

news2024/11/17 1:43:43

fork

  • 引言(程序地址空间)
  • 进程地址空间
    • 进程地址空间
    • mm_struct
  • 虚拟地址到物理地址的转化
  • 总结

引言(程序地址空间)

在之前的学习过程中,我们认识了内存与地址,并且了解了在程序地址空间中的基本分区,包括内核空间(用户代码不能访问)、内存映射段(文件映射,动态库,匿名映射)、数据段(静态区)、代码段(常量区):
在这里插入图片描述
在用户空间中,我们可以通过指针来访问其中的数据:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a = 10;  //栈
    int* pb = (int*)malloc(sizeof(int));  //堆
    static int c = 20;  //数据段

    printf("栈:%p\n堆:%p\n数据段:%p\n", &a, pb, &c);
    return 0;
}

在这里插入图片描述
可以看出,栈区的数据地址远高于堆区的地址,堆区的地址高于数据段的地址,大致的说明了上面图示的结构。

进程地址空间

我们知道,进程可以简单的理解为正在执行的程序
那么如果说每一个程序都有一套上面的地址空间,当多个进程并发执行的时候,一个地址空间中不就会存储多份不同的数据,出现冲突:

比如我们在fork创建子进程时,会有两个返回值存在同一变量中来区分父子进程(关于fork在后面会详细介绍)。
当我们在父子进程中同时打印返回值ret的地址时,发现他们的地址是相同的:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
    pid_t ret = 0;

    ret = fork();
    if(ret == 0) //子进程
    {
        printf("子进程:%p,:%d\n", &ret, ret);
    }
    else if(ret > 0) //父进程
    {
        printf("父进程:%p,:%d\n", &ret, ret);
    }
    return 0;
}

在这里插入图片描述

显然,“同一块空间” 中存储了两份不同的数据,这显然是不可能的,两份数据一定是存储在两个不同的物理内存中的。
这其实说明,这里我们打印出的地址,不是真正的物理内存地址,而是虚拟的内存地址。每一个进程在执行时,面对的都是这样的虚拟的地址空间,这就被称为进程地址空间

进程地址空间

有了上面的认识,所谓的程序地址空间的概念是不准确的,准确的说法应该是进程地址空间。这份空间是虚拟地址,对每一个进程都有一份虚拟地址空间。这份虚拟内存对于每一个进程而言都是相同的,都包含内核空间与用户空间以及更里面的分区。
而上面的例子中的变量名相同,地址相同,但是物理地址不同。说明在两个进程中的 “相同地址” 其实是被页表映射到了不同的物理内存中
在这里插入图片描述
当子进程中需要修改父进程中的一些变量的值时,首先会发生写时拷贝,建立一个新的映射,然后将子进程修改后的数据存储到一块新的物理内存空间中,这些步骤都是由操作系统完成的。
在之后的过程中,父进程或子进程的代码执行可以不受任何的影响,在访问数据时依旧是通过那个虚拟地址来访问的。也就是说,进程的代码与虚拟地址对于这个虚拟地址到底映射到哪块爱物理内存根本就不需要关心。

并且由于多个进程在并发工作时,在物理内存中的内存开辟就不可能是连续开辟的。如果我们的进程直接面对物理内存执行,那么数据结构的存在就没有了意义,数据的访问就会完全乱套。所以让每一个进程都面对一模一样的虚拟内存结构就是非常有必要的了

mm_struct

所以进程地址空间的本质是一个进程的可视范围。这个范围之中有着各种区域划分,这些区域是需要被操作系统管理的,所以类似于进程task_struct需要有一个数据结构来描述进程地址空间,这个数据结构就是mm_strucrt
其中空间中区域的划分就是一系列的startend变量,用来描述一块一块的区域。(我们可以在Linux的源码中找到相关定义):
在这里插入图片描述

而从进程task_struct数据结构中,有struct mm_struct*的结构体指针。可以通过这个结构体指针访问到该进程的mm_struct
在这里插入图片描述

在这里插入图片描述

虚拟地址到物理地址的转化

通过前面的认识,我们了解了页表是一个虚拟内存到物理内存的映射。
但是,如果页表只是一个单纯的映射表,其中包括一个虚拟地址与它对应的物理地址的话。那么页表将会非常大,我们可以简单计算一下:
以32位为例,进程地址空间共有从0x000000000xFFFFFFFF2^32个地址,也就是说页表中需要2^32项才能描述整个进程地址空间。每一项的大小都是8字节,一共就是8 * 2^32字节的空间,即32G的空间。页表的内容也一定是存储在内存中的,那么整个内存都存不下一个页表的内容,更何况有多个进程多个页表了。
所以页表的结构一定不是这样简单的映射表。

其实页表的结构是分两级的:
第一级页表有2^10项,其中存储的是第二级页表的地址;
第二级页表也有2^10项,其中存储的是物理内存中页框的首地址;
物理内存被分为一个个页框,页框的大小位4KB(2^12字节):

在这里插入图片描述

cpu在拿到32位的虚拟地址后,会将这个32位的虚拟地址分为3份,即前10位,中间10位与末尾的12位
在这里插入图片描述
前10位转化成一个10进制数,范围为 [0, 1023]表示在一级页表中位置的下标,由这个下标中的地址可以访问到一个二级页表
中间10位也转化成一个10进制数,范围为 [0, 1023]表示在二级页表中位置的下标,由这个下标中的地址可以访问到一个物理内存中的页框
末尾的12位转化成一个10进制数,范围为 [0, 2^12-1]表示这个空间在页框中的偏移量,正好一个页框的大小就是2^12个字节,由这个偏移量就可以在页框中访问到对应的物理地址
在这里插入图片描述

总结

到此,关于进程地址空间的基本知识就介绍完了
相信大家会对进程的内存体系有更好的理解

如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出

如果本文对你有帮助,希望一键三连哦

希望与大家共同进步哦

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

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

相关文章

AI语音机器人的发展

第一代AI语音机器人具体投入研发的开始时间不太清楚&#xff0c;只记得2017年的下半年就已经开始接触到成型的AI语音机器人&#xff0c;并且正式商用。语音识别效果还不多&#xff0c;大多都是接入的科大讯飞或者百度的ASR。 2018年算是AI语音机器人的“青春期”吧&#xff0c;…

如何在网上赚取零花钱?真实靠谱的六个方法

现如今&#xff0c;时代的不断进步和发展。网赚这个词对我们来说已经不再陌生&#xff0c;随着互联网的发展&#xff0c;许多朋友都希望在空闲时间利用上网多赚一份收入&#xff0c;但因为不懂又经常有人被骗&#xff0c;造成大部分对很多可以赚钱的项目都不敢相信了&#xff0…

二叉树简介

二叉树 二叉树是每个节点最多有两个子树的树结构&#xff0c;通常子树被称作“左子树”和“右子树”。 二叉树的遍历 二叉树的遍历主要有三种方式&#xff1a;前序遍历、中序遍历和后序遍历。 前序遍历&#xff1a;访问根节点 --> 遍历左子树 --> 遍历右子树中序遍历&…

OS进程管理

进程 文章目录 进程概念组成特征状态与转换组织方式链接方式索引方式 进程控制实现进程控制如何实现原语的“原子性” 进程通信(IPC)共享存储基于存储区共享基于数据结构的共享 消息传递直接通信方式间接通信方式 管道通信 线程实现方式用户级线程内核级线程 多线程模式状态与转…

RT-Thread: eeprom存储芯片 at24cxx软件包使用流程

说明&#xff1a;介绍 i2c 通讯接口的 eeprom at24cxx 读写测、试代码&#xff0c;代码基于 at24cxx 软件包实现。 使用步骤&#xff1a; * 1&#xff1a;在 RT-Thread Settings 中开启 【软件模拟I2C】 * 2&#xff1a;在 RT-Thread Settings 软件包中搜索 at24cxx 添加软件…

数据结构学习 jz38 字符串的排列

关键词&#xff1a;字典序排列 dfs 回溯 哈希 这种全排列题目可以考虑用下一个排列的方法做&#xff0c;这是最优解&#xff08;方法四&#xff09; 题目&#xff1a;套餐内商品的排列顺序 我的&#xff1a;[ 用时: 21 m 11 s ] 回溯 dfs 哈希表 方法一&#xff1a;我写的 …

Maven 基础安装配置及使用

大家好我是苏麟 , 今天聊聊Maven . Maven Maven , 是Apache公司下基于Java开发的开源项目 . 我们构建一个项目需要用到很多第三方的类库&#xff0c;需要引入大量的jar包。一个项目Jar包的数量之多往往让我们瞠目结舌&#xff0c;并且Jar包之间的关系错综复杂&#xff0c;一…

海外云手机助力企业拓展海外市场

在当前全球化的商业环境中&#xff0c;由于政策限制&#xff0c;许多企业面临着无法顺利将产品推广到国外的困境&#xff0c;使得海外市场的机遇白白流失。而随着科技的不断创新&#xff0c;一种解决企业海外拓展困境的工具应运而生&#xff0c;那就是海外云手机。本文将深入探…

手撕乘积(**Multiplication** **Product**): 穷举和图示(2) 点积的几何意义

手撕乘积(Multiplication & Product): 穷举和图示(2) 点积的几何意义 点乘 x 3 y 5 xNda np.arange(x) >>> array([0, 1, 2]) x2Nda xNda*21 >>> array([1, 3, 5]) yNda np.arange(1, y) >>> array([1, 2, 3, 4]) xyNda np.meshgrid(xN…

Linux系统使用docker部署Geoserver(简单粗暴,复制即用)

1、拉取镜像 docker pull kartoza/geoserver:2.20.32、创建数据挂载目录 # 统一管理Docker容器的数据文件,geoserver mkdir -p /mydata/geoserver# 创建geoserver的挂载数据目录 mkdir -p /mydata/geoserver/data_dir# 创建geoserver的挂载数据目录&#xff0c;存放shp数据 m…

01.15

#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();VideoCapture mv;mv.open("D:\\opencv\\heads\\01.mp4");//定义一个存放视频里读取到的一帧图像Mat src;//定义一个存…

配置华为设备NQA UDP Jitter检测VoIP业务抖动

组网需求 如图1所示&#xff0c;总部和子公司之间需要跨越外部网络进行通信&#xff0c;DeviceA和DeviceD为总部和子公司的网络出口设备&#xff0c;DeviceB和DeviceC为外部网络提供商的边缘设备。 总部和子公司之间经常要通过VoIP进行电话会议&#xff0c;要求双向时延小于2…

Java内置锁:深度解析ReentrantReadWriteLock并发类

ReentrantLock和ReentrantReadWriteLock是Java中用于线程同步的重要工具。ReentrantLock提供独占访问&#xff0c;适合需要保护共享资源不被并发修改的场景&#xff0c;同时支持可重入性&#xff0c;适用于递归操作。而ReentrantReadWriteLock则通过读写分离&#xff0c;允许多…

XTuner 微调 课程学习

大语言模型于海量的文本内容上&#xff0c;以无监督和半监督的方式进行训练的 模型微调的目的&#xff1a;使其在具体的使用场景或领域中输出更好的回答 增量预训练——给模型喂新的领域知识&#xff1b; 指令跟随或指令微调—— 基于海量的预训练数据训练出来的模型通常叫做…

[易语言]易语言部署yolox的onnx模型

【官方框架地址】 https://github.com/Megvii-BaseDetection/YOLOX 【算法介绍】 YOLOX是YOLO系列目标检测算法的进一步演变和优化。它由Megvii Technology的研究团队开发&#xff0c;是一个高性能、可扩展的对象检测器。YOLOX在保留快速处理速度的同时&#xff0c;通过引入一…

行业追踪,2024-01-15,含行业对应的etf

自动复盘 2024-01-15 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

Axure RP软件揭秘:设计师的秘密武器

Axure rp是一种快速原型设计工具&#xff0c;可以制作高度互动的HTML原型。设计师不仅可以使用Axure绘制线框图和原型&#xff0c;还可以在Axure rp中完成一系列用户体验设计。在本文中&#xff0c;我们将根据用户体验设计师的真实经验&#xff0c;触发用户体验设计师的实际工作…

Linux之引导和服务篇

系统引导是操作系统运行的开始&#xff0c;在用户能够正常登录之前&#xff0c;Linux的引导过程完成了一系列的初始化任务&#xff0c;并加载必要的程序和命令终端&#xff0c;为用户登录做好准备。 一. 引导过程 开机自检--->MBR引导--->GRUB菜单--->加载Linux内核-…

如何分析测试任务及需求(附分析流程)

测试分析 确认测试范围 根据测试项目的不同需求&#xff0c;有大致几类测试项目类型&#xff1a;商户/平台功能测试、支付方式接入测试、架构调整类测试、后台优化测试、性能测试、基本功能自动化测试。 测试项目需要按照文档要求进行测试需求分析&#xff0c;并给出对应的输出…

Spring MVC文件上传及全局异常处理器

添加依赖 <!--文件上传--> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version> </dependency>配置文件上传解析器 <!--配置文件上传解析器-…